C# 如何用多个输入参数实例化泛型类型?

C# 如何用多个输入参数实例化泛型类型?,c#,generics,C#,Generics,我有以下两种方法: Method1(int a, int b) { var type = Typ1(a, b); } Method2 { var type = Typ2(a, b); } 我想写一个通用方法来完成这项工作: GenericMethod<T>(int a, int b) { var type = new T(a, b); } GenericMethod(inta,intb) { var类型=新的T(a,b); } 但是T不接受任何输入参数

我有以下两种方法:

Method1(int a, int b)
{
    var type = Typ1(a, b);
}

Method2
{
    var type = Typ2(a, b);
}
我想写一个通用方法来完成这项工作:

GenericMethod<T>(int a, int b)
{
    var type = new T(a, b);
}
GenericMethod(inta,intb)
{
var类型=新的T(a,b);
}
但是T不接受任何输入参数。我怎样才能做到这一点

我知道使用
Activator.Instance(T,a,b)
我可以做到这一点,但它的性能成本很高

我还知道,我可以使用T()调用泛型类型的默认构造函数,然后设置属性,但在我的例子中,我想传递两个必需的参数

我不想引入一个没有参数的构造函数

对于泛型有什么方法可以做到这一点吗

谢谢,不用了

相反,您可以接受为您创建它们的委托:

GenericMethod<T>(int a, int b, Func<int, int, T> creator) {
    T t = creator(a, b);
}

GenericMethod(8, 9, (a, b) => new YourType(a, b));
GenericMethod(int a、int b、Func creator){
T=创造者(a,b);
}
一般方法(8,9,(a,b)=>新类型(a,b));
你也可以:

静态类创建者{
公共静态函数Func{get;set;}
}
通用方法(内部a、内部b){
T=Creator.Func(a,b);
}
Creator.Func=(a,b)=>newyourtype(a,b);

理论上,您需要使用一个。但是,唯一可用的构造函数约束是支持无参数构造函数
,其中T:new()


如果
Typ1
Typ2
共享一个基类,该基类使用2个整数定义属性,或者两者都支持一个接口来保证这些整数的设置,那么您可以在每个类上定义一个无参数构造函数,并使用一个附加约束来允许以后访问属性。

如果您不想使用Activator,您可以使用表达式树

创建您的factory类:

    public static class TypeFactory<T>
{
    private static Func<int, int, T> Func { get; set; }

    static TypeFactory()
    {
        TypeFactory<Type1>.Func = (a, b) => new Type1(a, b);
        TypeFactory<Type2>.Func = (a, b) => new Type2(a, b);
    }

    public static T Create(int a, int b)
    {
        return Func(a, b);
    }
}
公共静态类类型工厂
{
私有静态Func Func{get;set;}
静态类型工厂()
{
TypeFactory.Func=(a,b)=>新的Type1(a,b);
TypeFactory.Func=(a,b)=>新的Type2(a,b);
}
公共静态T创建(int a,int b)
{
返回函数(a,b);
}
}
然后像这样使用它:

        var type1 = TypeFactory<Type1>.Create(1, 2);
        var type2 = TypeFactory<Type2>.Create(1, 2);
var type1=TypeFactory.Create(1,2);
var type2=TypeFactory.Create(1,2);
公共静态类MyTypeFactory
{
静态MyTypeFactory()
{
MethodRunner.Func=(a,b)=>新类型1(a,b);
MethodRunner.Func=(a,b)=>新类型2(a,b);
}
公共静态T创建(int a,int b)
{
returnmethodrunner.Func(a,b);
}
静态类MethodRunner
{
公共静态函数Func{get;set;}
}
}
这看起来很有希望


静态ctor与静态字段初始值设定项一样本质上是线程安全的(CLR)?

应该注意的是,即使您对属于
new()
约束的泛型类型执行
new T()
,编译器也会将其转换为
Activator.CreateInstance()
调用,因此没有性能优势。唯一的解决方法是使用某种工厂模式,类似于SLaks对委托所做的。对基类型的T约束不会打开T上的构造函数,对于具有参数化构造函数的基,无法保证派生子级也会提供参数化构造函数。即使使用
new()
约束,编译器也只会将其转换为调用
Activator.CreateInstance()
,因此没有性能增益。你唯一得到的是编译时检查构造函数的存在。@Sven,你从哪里得到的?我在IL或C语言规范中没有看到关于约束的证据。我不确定这是否是规范要求的行为,但微软和Mono C编译器都是这样做的;你可以用ILSpy的反射器或类似的东西来检查它。@Sven,SLaks,你知道吗,别担心。我测试了错误的方法。我在
returnnewt()
returnactivator.CreateInstance()
上看到了IL
return(T)Activator.CreateInstance(typeof(T))
明显不同。为了使这一点值得一做,您需要存储编译后的表达式树(例如,在静态泛型字典中,如我的答案所示),以便以后可以重用它。否则,它最终会变得更慢。这是最快的方法吗?我非常喜欢静态泛型类方法,谢谢。与其他方法相比,它有最高的性能吗?您不应该在类本身中初始化它。您的初始值设定项将对每个类型参数运行一次。那么您有什么建议?我可以在类中使用一个锁来确保静态构造函数只运行一次,但我怀疑它会比Activator.CreateInstance()获得任何性能优势?您有这方面的代码示例吗?我不能把静态ctor移出课堂。我的意思是我可以移动它,但是什么时候应该调用它,从哪里调用它?我只需要在整个应用程序中调用它一次。我可以把它放在应用程序启动事件中!对静态字段初始值设定项被编译到静态ctor中。
        var type1 = TypeFactory<Type1>.Create(1, 2);
        var type2 = TypeFactory<Type2>.Create(1, 2);
public static class MyTypeFactory
{
    static MyTypeFactory()
    {
        MethodRunner<Type1>.Func = (a, b) => new Type1(a, b);
        MethodRunner<Type2>.Func = (a, b) => new Type2(a, b);
    }

    public static T Create<T>(int a, int b)
    {
        return MethodRunner<T>.Func(a, b);
    }

    static class MethodRunner<T>
    {
        public static Func<int, int, T> Func { get; set; }
    }
}