gpt4 book ai didi

C#:泛型、多态性和特化

转载 作者:行者123 更新时间:2023-11-30 16:25:50 26 4
gpt4 key购买 nike

我正在尝试使用具有特化的泛型。请参阅下面的代码。我想要做的是让运行时引擎理解函数的特化是基于类型可用的,它应该使用它而不是通用方法。是否可以不使用动态关键字

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)"
}

}

编辑

如果不使用关键字 dynamic 就无法实现我想要的效果,是否可以有任何优雅的方式来实现转换为具体类型而无需巨大的 enum\flag\switch-case?

编辑 - 可能是实现此目的的一种方式我想将其发布为答案,但这并不是真正基于多态性或重载,因此决定改为编辑。让我知道这是否有意义。

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)"
}

提前致谢,-尼尔。

最佳答案

我不认为有任何方法可以做到这一点。它根本不是 CLR 支持的执行时分派(dispatch)机制的一部分。你当然可以这样写:

public void PrintName<T>(T someT)
{
// This is assuming you want it based on the type of T,
// not the type of the value of someT
if (typeof(DerivedT).IsAssignableFrom(typeof(T))
{
PrintName((DerivedT)(object) someT);
return;
}
Console.WriteLine("PrintName<T>(T someT)");
}

...但这不是很令人愉快。

关于C#:泛型、多态性和特化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9486933/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com