tags:

views:

434

answers:

4

Is there a way to collect (e.g. in a List) multiple 'generic' objects that don't share a common super class? If so, how can I access their common properties?

For example:

class MyObject<T>
{
   public T Value { get; set; }
   public string Name { get; set; }

   public MyObject(string name, T value)
   {
      Name = name;
      Value = value;
   }
}

var fst = new MyObject<int>("fst", 42);
var snd = new MyObject<bool>("snd", true);

List<MyObject<?>> list = new List<MyObject<?>>(){fst, snd};

foreach (MyObject<?> o in list)
   Console.WriteLine(o.Name);

Obviously, this is pseudo code, this doesn't work.

Also I don't need to access the .Value property (since that wouldn't be type-safe).

EDIT: Now that I've been thinking about this, It would be possible to use sub-classes for this. However, I think that would mean I'd have to write a new subclass for every new type.

+3  A: 

C# doesn't support duck typing. You have 2 choices: interfaces and inheritance, otherwise you can't access similar properties of different types of objects.

aku
+6  A: 

Hi,

I don't think it is possible in C#, because MyObject is not a baseclass of MyObject. What I usually do is to define an interface (a 'normal' one, not generic) and make MyObject implement that interface, e.g.

interface INamedObject
{
    string Name {get;}
}

and then you can use the interface:

List<INamedObject> list = new List<INamedObject>(){fst, snd};

foreach (INamedObject o in list)
   Console.WriteLine(o.Name);

Did it answer your question?

Grzenio
A: 

The best way would be to add a common base class, otherwise you can fall back to reflection.

Motti
A: 

@Grzenio Yes, that exactly answered my question. Of course, now I need to duplicate the entire shared interface, but that's not a big problem. I should have thought of that...

@aku You are right about the duck typing. I wouldn't expect two completely random types of objects to be accessible.

But I thought generic objects would share some kind of common interface, since they are exactly the same, apart from the type they are parametrized by. Apparently, this is not the case automatically.

Tom Lokhorst
С# is a strong typed language. It means that Foo<X> and Boo<Y> are two completely different classes (unless they share common predecessor or interface), their properties are totally different as well regardless of similar signature.
aku
I realize that, its just that I thought Foo<X> and Foo<Y> would automatically share Foo as a base class (or something among those lines).This is apparently not the case. So I'll just have to write IFoo myself.Thanks of your help.
Tom Lokhorst