使用运行时类型执行的通用方法[重复]
Posted
技术标签:
【中文标题】使用运行时类型执行的通用方法[重复]【英文标题】:Generic Method Executed with a runtime type [duplicate] 【发布时间】:2009-10-22 12:46:09 【问题描述】:我有以下代码:
public class ClassExample
void DoSomthing<T>(string name, T value)
SendToDatabase(name, value);
public class ParameterType
public readonly string Name;
public readonly Type DisplayType;
public readonly string Value;
public ParameterType(string name, Type type, string value)
if (string.IsNullOrEmpty(name))
throw new ArgumentNullException("name");
if (type == null)
throw new ArgumentNullException("type");
this.Name = name;
this.DisplayType = type;
this.Value = value;
public void GetTypes()
List<ParameterType> l = report.GetParameterTypes();
foreach (ParameterType p in l)
DoSomthing<p.DisplayType>(p.Name, (p.DisplayType)p.Value);
现在,我知道我无法执行 DoSomething() 有没有其他方法可以使用这个功能?
【问题讨论】:
【参考方案1】:你可以,但它涉及到反思,但你可以做到。
typeof(ClassExample)
.GetMethod("DoSomething")
.MakeGenericMethod(p.DisplayType)
.Invoke(this, new object[] p.Name, p.Value );
这将查看包含类的顶部,获取方法信息,创建具有适当类型的泛型方法,然后您可以对其调用 Invoke。
【讨论】:
只是一个问题,p.Value 是一个字符串,因此调用将失败,除非 p.DisplayType 恰好是 typeof(string)。 很遗憾这是唯一的解决方案,嗯 好吧,我认为您可以在 4.0 中使用动态,它会推断出正确的通用参数类型,但我还没有机会验证它。并不是说它在幕后做的事情与上面的代码不同,但也许确实如此。【参考方案2】:this.GetType().GetMethod("DoSomething").MakeGenericMethod(p.Value.GetType()).Invoke(this, new object[]p.Name, p.Value);
应该可以。
【讨论】:
关于简洁:可以并不意味着应该。【参考方案3】:泛型类型不能在运行时按照您希望的方式指定。
最简单的选项是添加DoSomething
的非泛型重载,或者直接调用DoSomething<object>
并忽略p.DisplayType
。除非SendToDatabase
依赖于value
的编译时 类型(它可能不应该),否则给它一个object
应该没有错。
如果你不能这样做,你将不得不使用反射调用DoSomething
,你会受到很大的性能影响。
【讨论】:
【参考方案4】:首先我们需要将p.Value
转换为正确的类型,因为即使我们在编译时知道类型,我们也无法将字符串直接传递给方法...
DoSomething<Int32>( "10" ); // Build error
对于简单的数值类型和DateTime,我们可以使用
object convertedValue = Convert.ChangeType(p.Value, p.DisplayType);
现在我们可以使用反射来调用所需的泛型方法...
typeof(ClassExample)
.GetMethod("DoSomething")
.MakeGenericMethod(p.DisplayType)
.Invoke(this, new object[] p.Name, convertedValue );
【讨论】:
【参考方案5】:严格来说,您可以为此使用MethodInfo.MakeGenericMethod。
但我建议改为将 DoSomething 更改为非泛型形式,因为它是否真的应该是泛型的尚不清楚。
【讨论】:
我只是为了解释而简化了程序。这实际上是最优雅的解决方案,信不信由你。 :) 谢谢!以上是关于使用运行时类型执行的通用方法[重复]的主要内容,如果未能解决你的问题,请参考以下文章
使用 Lambda 表达式调用通用方法(以及仅在运行时知道的类型)