いくつかの基本クラスに制約されているジェネリック パラメーターを持つコンテナー クラスがあります。ジェネリックに提供される型は、基本クラス制約のサブです。サブクラスは、メソッド隠蔽 (new) を使用して、メソッドの動作を基本クラスから変更します (いいえ、それは私のコードではないため、仮想にすることはできません)。私の問題は、「新しい」メソッドが呼び出されないことです。コンパイラは、提供された型をサブではなくベースクラスと見なしているようです。まるでベースにアップキャストしたかのようです。
明らかに、ここで根本的なことを誤解しています。where T: xxx
ジェネリックはアップキャスト型ではなく、制約だと思いました。
このサンプル コードは基本的に、私が話していることを示しています。
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();
}
}
}
編集:
私の混乱は、これができることから来ていると思います
class SomeClass<T> where T: AnotherType, new()
{
T foo = new T();
}
そして、コンパイラがのインターフェイスを持っていると見なすことを理解していても、そうなると予想T
していました。のインターフェイスがコンパイル時に設定されていたとしても、実行時に の入力が行われると想定しました。宣言は実際に行っているため、ここでは誤解を招くようですT
T
AnotherType
T
T
T foo
AnotherType foo = new T();
foo
type として実際に宣言していないことを理解すると、メソッドの非表示が機能しないT
理由が理解できます。new
そして、それについて私が言わなければならないのはそれだけです。