tags:

views:

114

answers:

3
+7  A: 

No. The calls generated by the compiler are to the members it knows about at compile-time. That's the members exposed by ObjectA.

Any reason you're not using normal inheritance, with virtual/overridden methods?

Here's another example of the same kind of thing, by the way - the overloaded == operator for strings isn't used, even though T is string in the call to Foo:

using System;

class Test
{
    static bool Foo<T>(T first, T second)
        where T : class
    {
        return first == second;
    }

    static void Main()
    {
        string x = "hello";
        string y = new string(x.ToCharArray());

        Console.WriteLine(Foo(x, y));
    }
}
Jon Skeet
Thanks for your answer. I would use virtual/overridden methods, but I am inheriting from System.Windows.Form and trying to write my own implementation for a member that is not virtual.
Zach Johnson
Then you're not going to be able to access it like this. It sounds like you're trying to make it "nearly virtual" - it doesn't work like that.
Jon Skeet
Hm. I'd agree this is somewhat unintuitive, if you're used to C++ templates. C# does separate compilation of template classes, and knows only about ObjectA at that time. When the template is instantiated, the instantiated class is not recompiled with the added knowledge of ObjectB.
Pontus Gagge
A: 

This may not be an answer to your question, but I don't see the point with your approach (it may be because I only see a simplified example, though).

I would suggest using the following approach:

class ObjectA
{
    public virtual void Invoke()
    {
        // do some work
    }
}

class ObjectB : ObjectA
{
    public override void Invoke()
    {
        // do some other work
    }
}

class GenericNotNeededClass
{  
    public void DoWork(ObjectA item)  
    {  
        item.Invoke();  
    }  
}  


static void Main()  
{  
    GenericNotNeededClass nonGenericClass = new GenericNotNeededClass();  
    ObjectB objectB = new ObjectB();  
    nonGenericClass.DoWork(objectB);
}

I would believe that code does what you are looking for, based on your example code.

Fredrik Mörk
A: 

You define T to be of type ObjectA for your generic. If Invoke() were virtual it would work the way you are thinking, but because it is not, your generic calls the ObjectA implementation because that is what T is defined to be.

There is no virtual method table entry to point to the ObjectB implementation of Invoke() so this is all the runtime can call. If it were a virtual method there would be a method address in the VMT and it would act like you were thinking that it would.

Brian ONeil