使用运行时类型执行的通用方法

我有以下代码:

public class ClassExample { void DoSomthing(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 l = report.GetParameterTypes(); foreach (ParameterType p in l) { DoSomthing

(p.Name, (p.DisplayType)p.Value); } } }

现在,我知道我无法执行DoSomething()有没有其他方法可以使用此function?

你可以,但它涉及反思,但你可以做到。

 typeof(ClassExample) .GetMethod("DoSomething") .MakeGenericMethod(p.DisplayType) .Invoke(this, new object[] { p.Name, p.Value }); 

这将查看包含类的顶部,获取方法信息,创建具有适当类型的generics方法,然后可以在其上调用Invoke。

 this.GetType().GetMethod("DoSomething").MakeGenericMethod(p.Value.GetType()).Invoke(this, new object[]{p.Name, p.Value}); 

应该管用。

无法在运行时以您希望的方式指定generics类型。

最简单的选项是添加DoSomething的非generics重载,或者只是调用DoSomething并忽略p.DisplayType 。 除非SendToDatabase依赖于编译时类型的value (并且它可能不应该),否则给它一个object应该没有错。

如果你不能做到这些,你将不得不使用reflection调用DoSomething ,你将获得巨大的性能。

首先我们需要将p.Value转换为正确的类型,因为即使我们在编译时知道类型,我们也不能直接将字符串传递给方法…

 DoSomething( "10" ); // Build error 

对于简单的数字类型和DateTime,我们可以使用

 object convertedValue = Convert.ChangeType(p.Value, p.DisplayType); 

现在我们可以使用reflection来调用所需的generics方法……

 typeof(ClassExample) .GetMethod("DoSomething") .MakeGenericMethod(p.DisplayType) .Invoke(this, new object[] { p.Name, convertedValue }); 

严格说你可以使用MethodInfo.MakeGenericMethod 。

但我建议将DoSomething改为非genericsforms,因为它是否真的应该是通用的并不明显。