我的项目中有十几种方法(C#2.0),如下所示:
internal bool ValidateHotelStayEntity(DataRow row)
{
return (new HotelStayEntity(row)).Validate();
}
Run Code Online (Sandbox Code Playgroud)
......但是对于不同的"实体"类.(好吧,不是那么琐碎,我在这里简化了代码.)
它似乎是泛型的一个很好的候选者,我想出了这个:
internal bool ValidateEntity<T>(DataRow row) where T : EntityBase
{
return (new T(row)).Validate();
}
Run Code Online (Sandbox Code Playgroud)
当然我得到"无法创建类型参数'T'的实例,因为它没有new()约束"错误.
问题是这些"实体"类没有公共无参数构造函数,也没有在之后添加"行"数据的方法.由于EntityBase是公司框架的一部分,我无法控制它(即我无法改变它).
有没有办法解决?
Jon*_*eet 15
一种简单的方法是提供工厂功能:
internal bool ValidateEntity<T>(DataRow row, Func<DataRow, T> factory)
where T : EntityBase
{
return factory(row).Validate();
}
Run Code Online (Sandbox Code Playgroud)
并致电:
bool valid = ValidateEntity(row, x => new Foo(x));
Run Code Online (Sandbox Code Playgroud)
请注意,在这一点上,它比仅仅打电话更复杂
bool valid = new Foo(row).Validate()
Run Code Online (Sandbox Code Playgroud)
首先...
你真正想要在真实环境中实现什么并不是很清楚,但这种工厂/提供商方法在其他时候肯定是有用的.请注意,调用工厂的委托,也可以明显比使用更快的new T()
与约束,正如我前一阵子博客.在很多情况下,不过是不可知的,但值得了解.
编辑:对于.NET 2.0兼容性,您需要自己声明委托,但这很容易:
public delegate TResult Func<T, TResult>(T input);
Run Code Online (Sandbox Code Playgroud)
如果您真的使用的是C#2(而不是C#3,目标是.NET 2.0),那么您也无法使用lambda表达式,但您仍然可以使用匿名方法:
bool valid = ValidateEntity(row, delegate(DataRow x) { return new Foo(x); });
Run Code Online (Sandbox Code Playgroud)
另一种方法可能是涉及反射,但代价是编译时检查和性能下降:
internal bool ValidateEntity<T>(DataRow row)
{
object entity = Activator.CreateInstance(typeof(T), new object[] { row });
MethodInfo validate = typeof(T).GetMethod("Validate");
return (bool) validate.Invoke(entity, new object[]);
}
Run Code Online (Sandbox Code Playgroud)
请注意,即使实体没有共同的祖先,这也会起作用