[英]Call method on parameter of generic type
我想编写一个通用方法,作为输入有一个通用对象列表。 我想在每个列表项上调用一个方法。
我要做的是写一些像:
public void ResetPointProperties<T> (List<T> Points)
{
foreach (T point in Points)
{
point.Reset();
}
}
如何在列表项上调用Reset()
?
你快到了。 然而,缺少的是,就目前而言,编译器不知道每个T
是否具有reset()
方法。 因此,您必须向T
参数添加一个约束 ,该约束需要T
来实现接口或从声明这种reset()
方法的类继承。
例如, 假设你在某个地方有以下界面:
public interface IThing
{
void reset();
}
然后,您可以按如下方式声明上述方法:
public void ResetPointProperties<T> (List<T> Points)
where T : IThing
这强制传递给T
类型参数的任何类型都必须实现IThing
。 作为回报,编译器可以保证方法中的point
实际上具有可以调用的reset()
方法。
如果您的问题是“如何在T
上调用Reset()
” ,那么 - 要正确地执行 - 您需要引入泛型类型约束 。
您可以使用界面执行此操作:
public interface IResettable
{
void Reset();
}
并申请:
public void ResetPointProperties<T> (List<T> Points)
where T : IResettable
现在,当您调用ResetPointProperties()
方法时,必须使用List<T>
的参数,其中T
实现接口IResettable
。 例如一个Point
类:
public class Point : IResettable
{
public void Reset()
{
X = 0;
Y = 0;
}
}
好的,让我们看一下让它运行的所有可能方法:
A.通用约束
public void ResetPointProperties<T> (List<T> Points)
where T : ISomeInterface // interface must contain .Reset method
{
foreach (T point in Points)
point.Reset();
}
B.在调用方法之前键入检查和显式转换:
public void ResetPointProperties<T> (List<T> Points)
{
if(typeof(T) != typeof(Point)) return;
foreach (T point in Points)
{
Point p = point as Point;
p.Reset();
}
}
C.通过反射:
public void ResetPointProperties<T> (List<T> Points)
{
if(typeof(T) != typeof(Point)) return;
MethodInfo method = typeof(T).GetMethod("Reset");
foreach (T point in Points)
{
t.Invoke(point, null);
}
}
D.使用dynamic
:
public void ResetPointProperties<T> (List<T> Points)
{
foreach (dynamic point in Points)
{
point.Reset();
}
}
如果可能,最好的解决方案是使用接口和通用约束。 接下来将是强制转换然后执行某些操作(例如,在类是来自某个外部dll并且您无法控制它的情况下)。 通常不推荐反射和动力学,因为它们很慢,几乎不可能进行单元测试。
但有时使用反射和动力学可能会在一些复杂的情况下解决相当长的时间。
想象一下,这40个模型中每个模型都有40个数据库模型和3个视图模型,你想用某种方法映射它们......
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.