I have a container class that has a generic parameter that is limited to some base class. A type supplied in general is a subclause of the base class constraint. The subclass uses the hiding (new) method to change the behavior of the method from the base class (no, I cannot make it virtual, because this is not my code). My problem is that the "new" methods are not called, the compiler seems to think that the supplied type is a base class, not a sub, as if I had updated it to the base.
It is clear that I misunderstand something fundamental here. I thought the generic where T: xxx was a constraint, not an upcast type.
This sample code basically demonstrates what I'm talking about.
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace GenericPartialTest { class ContextBase { public string GetValue() { return "I am Context Base: " + this.GetType().Name; } public string GetOtherValue() { return "I am Context Base: " + this.GetType().Name; } } partial class ContextSub : ContextBase { public new string GetValue() { return "I am Context Sub: " + this.GetType().Name; } } partial class ContextSub { public new string GetOtherValue() { return "I am Context Sub: " + this.GetType().Name; } } class Container<T> where T: ContextBase, new() { private T _context = new T(); public string GetValue() { return this._context.GetValue(); } public string GetOtherValue() { return this._context.GetOtherValue(); } } class Program { static void Main(string[] args) { Console.WriteLine("Simple"); ContextBase myBase = new ContextBase(); ContextSub mySub = new ContextSub(); Console.WriteLine(myBase.GetValue()); Console.WriteLine(myBase.GetOtherValue()); Console.WriteLine(mySub.GetValue()); Console.WriteLine(mySub.GetOtherValue()); Console.WriteLine("Generic Container"); Container<ContextBase> myContainerBase = new Container<ContextBase>(); Container<ContextSub> myContainerSub = new Container<ContextSub>(); Console.WriteLine(myContainerBase.GetValue()); Console.WriteLine(myContainerBase.GetOtherValue()); Console.WriteLine(myContainerSub.GetValue()); Console.WriteLine(myContainerSub.GetOtherValue()); Console.ReadKey(); } } }
Edit:
I assume that my confusion comes from the fact that you can do it
class SomeClass<T> where T: AnotherType, new() { T foo = new T(); }
And I expected T be T , although I understand that the compiler will treat T as having AnotherType interface. I suggested that typing T will happen at run time, even if the T interface was installed at compile time. The declaration of T foo seems misleading here because it really does
AnotherType foo = new T();
As soon as I understand that it does not declare foo as a type T , it is clear why hiding the new method does not work.
And all I have to say about it.
ongle source share