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# / September 2007

Tip: Looking for answers? Try searching our database.

Feature request for C# Generic inheritence

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
Ido Samuelson - 26 Sep 2007 13:23 GMT
Hello,

What do you think about the following features:

public class GenericDecorator<T> : T
{

}

can leverage to a few things:

public interface IChannel
{
   void Connect();
   void Disconnect();
}

public class TcpChannel : IChannel
{
...
}

public class ChannelDescriber<T> : T where T : IChannel, class
{
    public string ChannelName {get; set;}
}

another more complicated example:

public class Extender<T,K> : T
{
   public K Data {get;set;}
}

which can be use to :
Extender<EventArgs,string> extender;

extender.Data (give the same ability as EventArgs<T> but more generic which can leverage other types that do not support generics.

Last is for delegates aka

delegate void extendDelegate<T,K>(K t) : T where T : delegate
// K should be added as first parameter.
and usage:

extendDelegate<ThreadStart,string> Start;

Start("hello world");

which means that even further we can do this:

System.Threading.Thread.Start(Start("ido",null)); // anonymous delegates feature

void Start(string name, object state);

you can vote for the feature in the following like:
https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID
=299676&wa=wsignin1.0

Signature

Best,

Ido Samuelson

Ben Voigt [C++ MVP] - 26 Sep 2007 23:09 GMT
The trouble is that .NET generics, unlike C++ templates, are completely
compiled in generic form.  However, all base classes must be known at
compile time.  Only C++ templates, which are made concrete before being
compiled, can inherit from template parameters.  However .NET classes can
use the curiously recurring template pattern which has some overlapping
applications.

Hello,

What do you think about the following features:

public class GenericDecorator<T> : T
{

}

can leverage to a few things:

public interface IChannel
{
   void Connect();
   void Disconnect();
}

public class TcpChannel : IChannel
{
...
}

public class ChannelDescriber<T> : T where T : IChannel, class
{
    public string ChannelName {get; set;}
}

another more complicated example:

public class Extender<T,K> : T
{
   public K Data {get;set;}
}

which can be use to :
Extender<EventArgs,string> extender;

extender.Data (give the same ability as EventArgs<T> but more generic which
can leverage other types that do not support generics.

Last is for delegates aka

delegate void extendDelegate<T,K>(K t) : T where T : delegate
// K should be added as first parameter.
and usage:

extendDelegate<ThreadStart,string> Start;

Start("hello world");

which means that even further we can do this:

System.Threading.Thread.Start(Start("ido",null)); // anonymous delegates
feature

void Start(string name, object state);

you can vote for the feature in the following like:
https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID
=299676&wa=wsignin1.0

Signature

Best,

Ido Samuelson

Ido Samuelson - 27 Sep 2007 04:28 GMT
This is correct. I thought that for generic inheritance, the compiler will
create an explicit type at compile time. Same way anonymous method works.

> The trouble is that .NET generics, unlike C++ templates, are completely
> compiled in generic form.  However, all base classes must be known at
[quoted text clipped - 62 lines]
> you can vote for the feature in the following like:
> https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID
=299676&wa=wsignin1.0
Ben Voigt [C++ MVP] - 27 Sep 2007 23:32 GMT
> This is correct. I thought that for generic inheritance, the compiler will
> create an explicit type at compile time. Same way anonymous method works.

No, compiler creates a special "generic" IL using concept of "type erasure".
JIT converts it to machine code.  There is only one copy of compiled machine
code shared for all types T (T being the generic argument) as long as T is a
reference type.  For value types, JIT compiles it separately to avoid boxing
overhead.

All binding (override resolution) is done knowing only the constraints and
not the final type.

Furthermore, derived classes must share the same v-table ordering of every
superclass.  This requires that the base class be known exactly.  Here's the
issue:

class Gen<T> : T where T : IList
{
   int IList.Count { get { ... } }
}

Let's compare the cases where T is List vs BindingList.

If T is List, then IList.Count.get must appear at the correct v-table offset
according to the inheritance order for List where IList appears, and the
ordinal for the Count getter.

But BindingList derives from Collection.  Collection has a different v-table
ordering.  It isn't possible to guarantee the same v-table location within
BindingList as within List, because BindingList must start with the same
v-table entries as Collection.

Therefore it isn't possible for a generic class to derive from a generic
parameter.

C++ templates are fully supported in .NET (only using the C++/CLI compiler),
however, and are compiled separately for each combination of parameters.
The result of instantiating a C++ template is a .NET non-generic ref-class.
Ido Samuelson - 28 Sep 2007 04:47 GMT
I know how the compiler works for the current generics. I was talking about
how it "will" work for the feature request. So for generic inheritance an
explicit code generated type will be created at compile time. This will
resolve the v-table issue because the base class will be known exactly.

so for your example

class Gen<T> : T where T : IList
{
  int IList.Count { get { ... } }
}

at runtime a new type will be created:

Class GenXXXList : List
{
 int IList.Count { get {... } }
}

and all the code refered to Gen<T> will be replaced with GenXXXList. (same
way as anonymous methods)

>> This is correct. I thought that for generic inheritance, the compiler
>> will create an explicit type at compile time. Same way anonymous method
[quoted text clipped - 36 lines]
> parameters. The result of instantiating a C++ template is a .NET
> non-generic ref-class.
Jon Skeet [C# MVP] - 28 Sep 2007 07:51 GMT
> I know how the compiler works for the current generics. I was talking about
> how it "will" work for the feature request. So for generic inheritance an
[quoted text clipped - 17 lines]
> and all the code refered to Gen<T> will be replaced with GenXXXList. (same
> way as anonymous methods)

So a Gen<List> used in one assembly wouldn't the same type as a
Gen<List> in another assembly? Sounds like a recipe for hard-to-
diagnose bugs.

Signature

Jon Skeet - <skeet@pobox.com>
http://www.pobox.com/~skeet   Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too

Ido Samuelson - 28 Sep 2007 08:31 GMT
isn't that the same case with anonymous methods or extension methods? in
some cases both can cause unexpected behaviors.

>> I know how the compiler works for the current generics. I was talking
>> about
[quoted text clipped - 23 lines]
> Gen<List> in another assembly? Sounds like a recipe for hard-to-
> diagnose bugs.
Ido Samuelson - 28 Sep 2007 08:39 GMT
Further, it is never a good idea to have the same class name, same type and
same namespace in different assemblies. So I really don't see a problem in
debugging.

> isn't that the same case with anonymous methods or extension methods? in
> some cases both can cause unexpected behaviors.
[quoted text clipped - 27 lines]
>> Gen<List> in another assembly? Sounds like a recipe for hard-to-
>> diagnose bugs.
Jon Skeet [C# MVP] - 28 Sep 2007 18:03 GMT
> Further, it is never a good idea to have the same class name, same type and
> same namespace in different assemblies. So I really don't see a problem in
> debugging.

It's completely different to that situation. It's perfectly reasonable
to use List<string> in two different places, but your way of working
would break it. If I were to declare an API of

public Gen<Stream> GetGen()

then the object returned by the method wouldn't be usable in a
different assembly.

Signature

Jon Skeet - <skeet@pobox.com>
http://www.pobox.com/~skeet   Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too

Jon Skeet [C# MVP] - 28 Sep 2007 18:01 GMT
> isn't that the same case with anonymous methods or extension methods? in
> some cases both can cause unexpected behaviors.

No - anonymous methods are only accessed within the same type, and
extension methods are completely different anyway.

Anonymous *types* are consistent within an assembly, but that's mostly
an optimisation - you can't expose an API in terms of anonymous types.

Signature

Jon Skeet - <skeet@pobox.com>
http://www.pobox.com/~skeet   Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too


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.