开发者

How to Instantiate a Generic Type With Multiple Input Parameters?

开发者 https://www.devze.com 2023-03-13 06:11 出处:网络
I have 2 methods a开发者_如何学编程s following: Method1(int a, int b) { var type = Typ1(a, b); } Method2

I have 2 methods a开发者_如何学编程s following:

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

Method2
{
    var type = Typ2(a, b);
}

I'd like to write a generic method which does the work:

GenericMethod<T>(int a, int b)
{
    var type = new T(a, b);
}

But T doesn't accept any input parameter. How could I achieve this?

I know using Activator.Instance(T, a, b) I can do that but it has a high performance cost.

I also know that I can call the default constructor of a generic type using T() then setting the properties,but in my case, I'd like to pass 2 parameters which are compulsory.

I don't want to introduce a constructor with no parameter.

Is there any way to do this with generics?

Thanks,


Create your factory class:

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

Then use it like this:

        var type1 = TypeFactory<Type1>.Create(1, 2);
        var type2 = TypeFactory<Type2>.Create(1, 2);


No.

Instead, you can accept a delegate that creates them for you:

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

You could also store these creators in a generic static class:

static class Creator<T> {
    public static Func<int, int, T> Func { get; set; }
}
GenericMethod<T>(int a, int b) {
    T t = Creator<T>.Func(a, b);
}


Creator<YourType>.Func = (a, b) => new YourType(a, b);


If you don't want to use Activator, you could use an expression tree. Incorrect number of parameters supplied for lambda declaration


In theory, you need to use a generic type constraint. However, the only constructor constraint available is support for a parameterless constructor where T : new().

If Typ1 and Typ2 share a base class which defines properties using the 2 integers or both support an interface guaranteeing setters for those integers you could define a parameterless constructor on each class and use an additional constraint to allow later access to the properties.


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

This looks promising?!

is a static ctor thread-safe by nature (CLR) like static field initializers?

0

精彩评论

暂无评论...
验证码 换一张
取 消