我想用專業化的泛型。請參閱下面的代碼。我想要做的是讓運行時引擎明白,功能的專業化是基於類型可用,它應該使用,而不是通用的方法。是否可能沒有使用關鍵字動態?C#:泛型,多態和專業化
public interface IUnknown
{
void PrintName<T>(T someT);
}
public interface IUnknown<DerivedT> : IUnknown
{
//***** I am trying to make runtime engine understand that method below is
//***** specialization of void PrintName<T>(T someT);
void PrintName(DerivedT derivedT);
}
public class SoAndSo<DerivedT> : IUnknown<DerivedT>
{
public void PrintName<T>(T someT) { Console.WriteLine("PrintName<T>(T someT)"); }
public void PrintName(DerivedT derivedT) { Console.WriteLine("PrintName(DerivedT derivedT)"); }
}
public class Test
{
public static void TestIt()
{
List<IUnknown> unknowns = new List<IUnknown>();
unknowns.Add(new SoAndSo<int>());
unknowns.Add(new SoAndSo<string>());
//*** statement below should print "PrintName(DerivedT derivedT)"
unknowns[0].PrintName(10);
//*** statement below should print "PrintName<T>(T someT)"
unknowns[0].PrintName("abc");
//********** code snippet below works exactly as expected ************
dynamic d;
d = unknowns[0];
d.PrintName(10); // <=== prints "PrintName(DerivedT derivedT)"
d.PrintName("abc"); // <=== prints "PrintName<T>(T someT)"
}
}
編輯
如果沒有什麼辦法可以達到我想要不使用關鍵字動態的,可以有任何優雅的方式來實現鑄造具體類型而無需龐大的枚舉\標誌\切換情況?
編輯 - 可能是一種方式實現這一 我想張貼此作爲一個答案,但是,這不是真正基於多態性或超載所以決定把作爲一個編輯來代替。讓我知道這是否合理。
public abstract class IUnknown
{
public abstract void PrintName<T>(T someT);
}
public abstract class IUnknown<DerivedT /*, DerivedType*/> : IUnknown //where DerivedType : IUnknown<DerivedT, DerivedType>
{
MethodInfo _method = null;
//***** I am trying to make runtime engine understand that method below is
//***** specialization of void PrintName<T>(T someT);
public override sealed void PrintName<T>(T derivedT)
{
bool isSameType = typeof(T) == typeof(DerivedT);
if (isSameType && null == _method)
{
//str = typeof(DerivedT).FullName;
Type t = GetType();
_method = t.GetMethod("PrintName", BindingFlags.Public |
BindingFlags.Instance,
null,
CallingConventions.Any,
new Type[] { typeof(T) },
null);
}
if (isSameType && null != _method)
{
_method.Invoke(this, new object[] { derivedT });
}
else
{
PrintNameT(derivedT);
}
}
public virtual void PrintNameT<T>(T derivedT)
{
}
public virtual void PrintName(DerivedT derivedT) { Console.WriteLine("PrintName(DerivedT derivedT)"); }
//public static DerivedType _unknownDerivedInstance = default(DerivedType);
}
public class SoAndSo<DerivedT> : IUnknown<DerivedT> //, SoAndSo<DerivedT>>
{
//static SoAndSo() { _unknownDerivedInstance = new SoAndSo<DerivedT>(); }
public override void PrintNameT<T>(T someT) { /*Console.WriteLine("PrintNameT<T>(T someT)");*/ }
public override void PrintName(DerivedT derivedT) { /*Console.WriteLine("PrintName(DerivedT derivedT)");*/ }
}
public static class Test
{
public static void TestIt()
{
List<IUnknown> unknowns = new List<IUnknown>();
unknowns.Add(new SoAndSo<int>());
unknowns.Add(new SoAndSo<float>());
//*** statement below should print "PrintName(DerivedT derivedT)"
unknowns[0].PrintName(10);
//*** statement below should print "PrintName<T>(T someT)"
unknowns[0].PrintName(10.3);
//*** statement below should print "PrintName(DerivedT derivedT)"
unknowns[1].PrintName(10);
//*** statement below should print "PrintName<T>(T someT)"
unknowns[1].PrintName(10.3f);
System.Diagnostics.Stopwatch stopWatch = new System.Diagnostics.Stopwatch();
stopWatch.Start();
for (int i = 0; i < 1000000; ++i)
{
unknowns[0].PrintName(10.3);
}
stopWatch.Stop();
System.Diagnostics.Trace.TraceInformation("Milliseconds: {0}", stopWatch.ElapsedMilliseconds);
//********** code snippet below works exactly as expected ************
dynamic d;
d = unknowns[0];
d.PrintName(10); // <=== prints "PrintName(DerivedT derivedT)"
d.PrintName("abc"); // <=== prints "PrintName<T>(T someT)"
}
在此先感謝, -Neel。
謝謝。你是對的 - 我正在尋找基於泛型的多態而不是類型參數。好東西是動態似乎按預期工作,壞事是我現在無法升級到.NET 4.0。 – 2012-02-28 18:11:09