简体   繁体   中英

How to Instantiate a Generic Type With Multiple Input Parameters?

I have 2 methods as 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?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM