不带new()的泛型
本文关键字:泛型 new 不带 | 更新日期: 2023-09-27 18:21:46
我的项目(C#2.0)中有十几个方法,如下所示:
internal bool ValidateHotelStayEntity(DataRow row)
{
return (new HotelStayEntity(row)).Validate();
}
但用于不同的"实体"类。(好吧,不是那么琐碎,我已经简化了这里的代码。)
它看起来像是仿制药的一个很好的候选者,我想出了这个:
internal bool ValidateEntity<T>(DataRow row) where T : EntityBase
{
return (new T(row)).Validate();
}
当然,我得到了"无法创建类型parameter‘T’的实例,因为它没有new()约束"的错误。
问题是,这些"实体"类没有公共的无参数构造函数,也没有在之后添加"行"数据的方法。由于EntityBase是公司框架的一部分,我无法控制它(即我无法更改它)。
有办法解决这个问题吗?
一个简单的方法是提供一个工厂函数:
internal bool ValidateEntity<T>(DataRow row, Func<DataRow, T> factory)
where T : EntityBase
{
return factory(row).Validate();
}
并呼叫:
bool valid = ValidateEntity(row, x => new Foo(x));
请注意,在这一点上,它比仅仅调用更复杂
bool valid = new Foo(row).Validate()
首先。。。
目前还不清楚你在实际环境中想要实现什么,但这种工厂/提供商的方法在其他时候肯定会很有用。注意,调用工厂委托也可能比使用带约束的new T()
快很多,正如我不久前在博客中所写的那样。在许多情况下是不可逆的,但值得了解。
编辑:为了与.NET 2.0兼容,您需要自己声明委托,但这很容易:
public delegate TResult Func<T, TResult>(T input);
如果真的使用C#2(而不是以.NET 2.0为目标的C#3),那么你也不能使用lambda表达式,但你仍然可以使用匿名方法:
bool valid = ValidateEntity(row, delegate(DataRow x) { return new Foo(x); });
另一种方法可能是以编译时检查和降低性能为代价进行反射:
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[]);
}
请注意,即使实体没有共同的祖先,这也会起作用
@JohnLaunchers的工厂方法解决方案示例:
internal bool ValidateEntity<T>(DataRow row, Func<DataRow, T> factory) where T : EntityBase
{
return (factory(row)).Validate();
}
您可以这样做:
internal bool ValidateEntity<T>(DataRow row) where T : EntityBase
{
return ((T)Activator.CreateInstance(typeof(T), new object[] { row })).Validate();
}