3

如何创建一个泛型类,该类允许具有构造函数的类型采用一个字符串参数并实现 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 库一起使用。

4

3 回答 3

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); });
于 2011-03-31T06:57:34.217 回答
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();
    }

}

注意:反射很慢,所以你必须考虑到这一点

于 2011-03-31T11:27:06.613 回答
0

你不能。您只能创建一个强制执行的约束,即您的类具有无参数构造函数new()如您所知,对此的约束是。

ToString()对每种类型都可用,因为它是在 上定义的,Object并且每种类型都继承自Object. 但是,您无法知道或强制执行您的类型是否提供了自己的ToString().

为确保,类型参数实现了两个特定方法,将它们放入接口并将类型参数约束到该接口并使您的类实现该接口。

于 2011-03-31T06:56:13.663 回答