Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

.NET Forum / Languages / C# / November 2007

Tip: Looking for answers? Try searching our database.

generics + inheritance

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
Richard Friend - 06 Nov 2007 17:30 GMT
Does anyone know how to get round this problem?

using System;
using System.Collections.Generic;
using System.Text;

namespace ClassLibrary1
{
   public class BaseClass
   {
       public int counter = 0;
   }
   public class GenericClass<T> : BaseClass where T : BaseClass,new()
   {
       public T IncrementCounterAndCopy()
       {
            T t = new T();
            t.counter = this.counter+1;
            return t;
       }
   }
   public class TestClass1 : GenericClass<TestClass1>
   {
   }
   public class TestClass2 : TestClass1
   {
   }

   public class TestIt
   {
       public void x()
       {
           //works ok
           TestClass1 t1 = new TestClass1();
           TestClass1 t2 = t1.IncrementCounterAndCopy();

           TestClass2 tt1 = new TestClass2();
           //How can i ensure the return type is of the actual type of my
class
           //WITHOUT making all classes in the chain also generic...?
           //Possible??
           TestClass2 tt2 = t1.IncrementCounterAndCopy(); //compiler error
here...
       }
   }
}
Nicholas Paldino [.NET/C# MVP] - 06 Nov 2007 17:45 GMT
Richard,

   I'm not sure what you are getting at.  The return type of
t1.IncrementCounterAndCopy is TestClass1, which you can't assign to tt2,
which is TestClass2.

   Now, I am assuming you are trying to do something like you want
TestClass2 to inherit from TestClass1, and you want the type parameter
passed to GenericClass in that inheritance chain to be TestClass2.

   Unfortunately, the only way to do this is, as you said, to place a type
parameter in each level of the inheritance chain, and pass the type all the
way down.

Signature

         - Nicholas Paldino [.NET/C# MVP]
         - mvp@spam.guard.caspershouse.com

> Does anyone know how to get round this problem?
>
[quoted text clipped - 42 lines]
>    }
> }
Richard Friend - 06 Nov 2007 17:54 GMT
Hi

Thanks for the prompt response.

I feared this was the answer, i just mocked up a quick example of a more
complex problem im having.

This is a quick mock of what some existing code i have looks like

public class User : DataBoundComponent<User>
{
}

i then extend that class
public class SpecialUser : User
{
}

How can i ensure that the generic underlying class for SpecialUser gets my
new type 'specializeduser' rather than the base class type?

This is due to my delegates being generic also, in the DataBoundComponent i
have this

public event EventHandler<DataBoundComponentCreatedEventArgs<T>>
ItemCreated;

now when i try to wire a delegate like so

specialuser.ItemCreated =delegate(object
sender,DataBoundComponentCreatedEventArgs<SpecialUser> e)
               {
                   e.Item.Apps =
Applications.SelectApplications(e.Item.FaceBookProfileId);
               });

obviously the underlying DataBoundComponents generic type is User not
specialUser so the event args do not match up...

Since im unable to change the User class, im just going to have to create
SpecialUser from the generic class and duplicate all the existing code in
the user class, grrrrrrr

> Richard,
>
[quoted text clipped - 56 lines]
>>    }
>> }
Richard Friend - 06 Nov 2007 18:08 GMT
Well im just going to create my SpecialUser class with its new properties
and create a property to reference the instance of  the user class.

But wouldn't it be possible for c# to have some sort of keyword for this,
its not like the compiler doesnt know the type of the concrete class since
its clearly throwing a compiler error already...

something like (pseudo)

class GenericClass<T> where T : new()
{
   public T t = new T();
}
class MyClass : GenericClass<mytype>
{

}
class MyClass2 : MyClass
{
}
MyClass x = new MyClass();
MyClass2 y = new MyClass2();

x.t.GetType() would be MyClass
y.t.GetType() would be MyClass2

That would be pretty awsome.
Nicholas Paldino [.NET/C# MVP] - 06 Nov 2007 18:17 GMT
Richard,

   I can't say I've had a use for such a thing, but I can see where it
would be useful.  Unfortunately, you can get around it easily now by adding
a type parameter to your derived classes.  That's ultimately what would keep
it from being made into a language feature (the ease with which you can
implement this using the current language features).

Signature

         - Nicholas Paldino [.NET/C# MVP]
         - mvp@spam.guard.caspershouse.com

> Well im just going to create my SpecialUser class with its new properties
> and create a property to reference the instance of  the user class.
[quoted text clipped - 23 lines]
>
> That would be pretty awsome.
Ben Voigt [C++ MVP] - 07 Nov 2007 14:28 GMT
> Hi
>
[quoted text clipped - 16 lines]
> How can i ensure that the generic underlying class for SpecialUser gets my
> new type 'specializeduser' rather than the base class type?

You can't, because then User would no longer be a superclass of SpecialUser
in the general case.  Only when the type argument is limited to
contravariant usage would such a thing be possible even theoretically.

Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.