如何创建一个泛型类,它允许类型构造函数接受一个字符串参数并实现ToString并实现两个函数,如下所示。
class Convert<T>:ConverterBase
where T:new()
{
public override object StringToField(string from)
{
try
{
return new T(from);
}
catch (ArgumentException exception)
{
ThrowConvertException(from, exception.Message);
return null;
}
}
public override string FieldToString(object from)
{
return from.ToString();
}
}
注意: ConvertBase是FileHelpers csv阅读器库中的抽象类。我已经有了与csv中的字段对应的类,不想创建继承ConvertBase的单独类,以便与FileHelpres库一起使用。
答案 0 :(得分:2)
无法使用构造函数约束(new()
)来约束除空构造函数之外的任何内容。解决这个问题的一种方法是使用lambda表达式。例如
class Convert<T>:ConverterBase {
private Func<string, T> _factory;
public (Func<string, T> factory) {
_factory = factory;
}
public override object StringToField(string from) {
try {
return _factory(from);
} ...
}
}
现在我可以创建Convert<T>
的实例并使用lambda表达式转发到类型
new Convert<Foo>(s => new Foo(s));
编辑 C#2.0实施,因为OP坚持2.0
public delegate TResult Func<T, TResult>(T arg);
new Convert<Foo>(delegate (string s) { return new Foo(s); });
答案 1 :(得分:0)
你做不到。您只能创建一个强制执行的约束,即您的类具有无参数构造函数。正如您所知,对此的约束是new()
。
ToString()
适用于所有类型,因为它在Object
上定义,并且每种类型都继承自Object
。但是,您无法了解或强制执行此类型是否提供了自己的ToString()
实现。
为了确保,type参数实现了两个特定的方法,将它们放入一个接口并将type参数约束到该接口,并使您的类实现该接口。
答案 2 :(得分:0)
您可以在那里创建一个存储转换器函数并实现两个成员的基类,之后您可以继承该成员并仅将字符串提供给对象转换
public abstract class Convert<T>:ConverterBase
{
private Func<string, T> ConverterFunction {get;set;}
protected Convert(Func<string, T> converterFunction)
{
ConverterFunction = converterFunction;
}
public override object StringToField(string from)
{
try
{
return ConverterFunction(from);
}
catch (ArgumentException exception)
{
ThrowConvertException(from, exception.Message);
return null;
}
}
public override string FieldToString(object from)
{
return from.ToString();
}
}
稍后创建一些简单的派生类,例如:
public class ConvertMyClass:ConverterBase<MyClass>
{
public ConvertMyClass()
:base(from => new MyClass(from)
{
}
}
希望这会有所帮助:)请记住从以下位置下载最新的稳定版本: http://teamcity.codebetter.com/viewLog.html?buildId=lastSuccessful&buildTypeId=bt66&tab=artifacts&guest=1
编辑:使用反射,您可以尝试:
class Convert<T>:ConverterBase
{
public override object StringToField(string from)
{
try
{
return Activator.CreateInstance(typeof(T), from);
}
catch (ArgumentException exception)
{
ThrowConvertException(from, exception.Message);
return null;
}
}
public override string FieldToString(object from)
{
return from.ToString();
}
}
注意:反射很慢,因此您必须考虑到这一点