如何在C#泛型中指定可以从字符串构造的T?(泛型类型约束)

如何在C#泛型中指定可以从字符串构造的T?(泛型类型约束),c#,.net,generics,constraints,.net-4.5,C#,.net,Generics,Constraints,.net 4.5,我想为我的T指定所需的默认构造函数选项: public interface IParameter<T> /* where T : T(string) */ { T Value { get; set; } } 或者至少是这样: Value = "bla"; Value = new T("bla"); myPrm.AssignValue("Hello, World!"); 那么如何在C#泛型中指定可以从字符串构造的T呢?你不能,因为在泛型类型约束中,你不能

我想为我的T指定所需的默认构造函数选项:

  public interface IParameter<T>  /* where T : T(string) */ { 
     T Value { get; set; }
  }
或者至少是这样:

Value  = "bla";
Value = new T("bla");
myPrm.AssignValue("Hello, World!");

那么如何在C#泛型中指定可以从字符串构造的T呢?

你不能,因为在泛型类型约束中,你不能说类型必须有一个特定的构造函数(只是它必须有一个无参数的构造函数),也不能说它必须有特定的方法/运算符

但是

公共接口IFromString
{
void反序列化fromstring(string str);
}
公共类MyType:IFromString
{
公共价值观;
public void反序列化fromstring(string str)
{
Value=int.Parse(str);
}
}
公共接口i参数,其中T:IFromString,new()
{
T值{get;set;}
}
公共类参数:IPParameter,其中T:IFromString,new()
{
T值{get;set;}
公共空荷载(字符串str)
{
值=新的T();
反序列化fromstring(str);
}
}
一个经典的例子。。。表示类型可以从(某物)反序列化的接口(xml通常为:-)

使用:

参数参数=新参数();
参数.Load(someStringLoadedFrom某地);

不幸的是,这种限制是不合法的。仅允许无参数构造函数约束:

where T : new()

不能在接口中指定构造函数。根据您的需求,您可以使用抽象类:

伪代码不在带VS的机器上:

public abstract class BaseParameter<T>
{ 
    public abstract void BaseParameter(string something);

    T Value { get; set; }
}
公共抽象类BaseParameter
{ 
公共抽象void BaseParameter(字符串某物);
T值{get;set;}
}
不幸的是,C#没有为泛型参数提供任意构造函数签名限制。仅,其中最近的一个是。但是,它仅用于强制执行无参数构造函数

但是,您可以通过使用接受
字符串并返回
T
的factory对象来解决此缺点。首先,为这些factory对象定义一个接口:

public interface IFactory<T>
{
    T Create(string str);
}
作为如何使用此函数的示例,我们假设变量
myPrm
是的一个实例,它使用适当的类型参数实现
ipParameter
接口。然后,您可以调用如下内容:

Value  = "bla";
Value = new T("bla");
myPrm.AssignValue("Hello, World!");

这是如何回答这个问题的?OP不是询问接口的构造函数,而是询问需要
T
中的特定构造函数。你不能有一个具有类名称的方法,也不能告诉你需要一个以这种方式实现的构造函数(我不确定
BaseParameter(string something)
是一个方法还是一个构造函数)@O.R.Mapper建议OP可能希望根据实际需求查看抽象类,而不是接口。它们在不同的时间有用。@xanatos-Constructor。正如我所说,不是在PC上使用VS,所以不能100%证明,而是想显示抽象类,因为很多人在使用接口等时忽略了这一点。@Belogix没有抽象构造函数。您定义了一个与类同名的抽象方法,这也是不允许的。
string
不能被子类化,那么让它成为泛型有什么意义呢?@jeroenvanevel:这不是关于子类化,它是关于一个任意类型的
T
有一个接受
string
参数的构造函数。任何T都有ToString(地址、时间、URL等),许多这样的类型都可以从string构造。啊,那么它是关于一个以字符串为参数的构造函数?因为这与所展示的第一个用法完全不同。这似乎是一个更好的方法。在某些方面,稍微好一点的方法可能是指定任何类型都不能合法地实现
IFromString
,除非它或父类型包含静态工厂方法
T ConstructFromString(String st)
,并且有一个静态泛型类,它可以使用缓存委托为任何特定类型
U:IFromString
调用此类方法。第一次为任何类型
U
访问它时,都需要进行反射查找,但之后需要进行简单的委托分派。这将避免需要新的约束。
public static class ParameterUtilities
{
    public static void AssignValue<TFactory, T>(this IParameter<TFactory, T> prm, string str)
        where TFactory : new(), IFactory<T>
    {
        var factory = new TFactory();
        prm.Value = factory.Create(str);
    }
}
myPrm.AssignValue("Hello, World!");