我想知道,在下面的示例中,if
中的TrickyGenericMethod
语句是一个坏主意,或者在某些情况下它会没问题。在我的例子中,我有一个工厂方法,它使用泛型参数来产生正确的结果。不幸的是,如果传入的对象的类型引用是对接口或抽象类的引用,则它将产生不正确的结果,因为T
不是对象的实际类型。
class Program
{
static void Main(string[] args)
{
HasGenericMethod hgm = new HasGenericMethod();
Console.WriteLine(hgm.GenericMehtod("string"));
Console.WriteLine(hgm.GenericMehtod((object)"object"));
Console.WriteLine();
Console.WriteLine(hgm.TrickyGenericMethod("string"));
Console.WriteLine(hgm.TrickyGenericMethod((object)"object"));
Console.ReadKey();
}
}
class HasGenericMethod
{
public string GenericMehtod<T>(T param)
{
return "Type of T:\t" + typeof(T) + "\tType of param:\t" + param.GetType();
}
public string TrickyGenericMethod<T>(T param)
{
if (typeof(T) != param.GetType())
{
return TrickyGenericMethod((dynamic)param);
}
return "Type of T:\t" + typeof(T) + "\tType of param:\t" + param.GetType(); ;
}
}
答案 0 :(得分:4)
是TrickyGenericMethod中的if语句是个坏主意
是的,它看起来像我。特别是,如果使用内部类型的值从一个不同的程序集中调用它(并且它通过此路径一次),“执行时编译器”将使用dynamic
调用的最佳可访问类型。所以你最终会出现堆栈溢出。
编辑:该示例代码...
// Library.cs
using System;
public class Library
{
public static void Foo<T>(T value)
{
Console.WriteLine("{0} : {1}", typeof(T), value.GetType());
if (typeof(T) != value.GetType())
{
dynamic d = value;
Foo(d);
}
}
}
// Test.cs
class Internal {}
class Program
{
static void Main(string[] args)
{
Library.Foo<object>(new Internal());
}
}
结果:
System.Object : Internal
System.Object : Internal
...
System.Object : Internal
Process is terminated due to StackOverflowException.
可能还有其他类似的情况,它也不太有效。我会尽量避免依赖typeof(T) == value.GetType()
。
您可以无条件地使用动态类型调用私有实现方法,这样您最终只会尝试一次,最终会采用“尽力而为”的方法。
答案 1 :(得分:0)
第二,你正在测试T何时等于GetType()
并递归直到它,因此只需直接使用GetType()
的结果并完成它。