带字符串参数的构造函数的通用约束?

发布于 2024-10-28 13:18:18 字数 726 浏览 2 评论 0原文

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

How to create a generic class that allows types which has constructor taking one string argument and implements ToString and implements Two functions as below.

    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();
        }

    }

Note:
ConvertBase is a abstract class in FileHelpers csv reader library. I already have classes that corresponds to my fields in csv, didn't want to create seperate Classes that inherit ConvertBase inorder to use with the FileHelpres library.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

烂柯人 2024-11-04 13:18:18

无法使用构造函数约束 (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 的实例,并使用 lambda 表达式转发到

new Convert<Foo>(s => new Foo(s));

EDIT C# 2.0 实现类型的构造函数,因为 OP 仍停留在 2.0 上

public delegate TResult Func<T, TResult>(T arg);

new Convert<Foo>(delegate (string s) { return new Foo(s); });

There is no way to use the constructor constraint (new()) to constrain to anything other than an empty constructor. One way to work around this though is to use a lambda expression. For example

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);
    } ...
  }
}

Now I can create instances of Convert<T> and use a lambda expression to forward to the constructor of the type

new Convert<Foo>(s => new Foo(s));

EDIT C# 2.0 implementation since the OP is stuck with 2.0

public delegate TResult Func<T, TResult>(T arg);

new Convert<Foo>(delegate (string s) { return new Foo(s); });
怼怹恏 2024-11-04 13:18:18

您好,您可以创建一个基类来存储转换器函数并实现两个成员,之后您可以继承它并仅提供字符串到对象的转换

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();
    }

}

注意:反射很慢,所以你必须采取它考虑到

Hi there you can create a base class that stores the converter function and implements both members, after that you can inherit from it and only provide the string to object convertion

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();
    }

}

Later create some simple derived classes for example:

public class ConvertMyClass:ConverterBase<MyClass>
{
    public ConvertMyClass()
        :base(from => new MyClass(from)
    { 
    }
}

Hope this helps :) Remember to download the last stable version from:
http://teamcity.codebetter.com/viewLog.html?buildId=lastSuccessful&buildTypeId=bt66&tab=artifacts&guest=1

EDIT: Using Reflection you can try:

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();
    }

}

NOTE: Reflection is slow, so you must take that into account

つ低調成傷 2024-11-04 13:18:18

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

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

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

You can't. You can only create a constraint that enforces, that your class has a parameterless constructor. The constraint for that is new(), as you know.

ToString() is available on every type, because it is defined on Object and every type inherits from Object. However, you can't know or enforce, whether your type provides it's own implementation of ToString().

To make sure, the type parameter implements two specific methods, put them into an interface and constrain the type parameter to that interface and make your class implement that interface.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文