Selena
Selena

Reputation: 2268

Translating a Java generic method with a 'Class<? extends Something>' parameter into a C# implementation

I am translating a Java API into C# and I have method like this:

public void addSpecificImplementation(String name, Class<? extends SomeInterface> implClass)

I know that Type is the equivalent of java.lang.Class in C#. I don't know how to write this method to take a parameter of 'Type' with the constraint that it must be a sub-type of a specific interface. How is this done in C#?

Here is the actual java implementation:

public void addSpecificImplementation(String name, Class<? extends SomeInterface> implClass) {
    Constructor<BeanT> ctor = implClass.getConstructor();
    myInstance = ctor.newInstance();
    ..... add the instance to some data structure.....
}

Upvotes: 2

Views: 137

Answers (2)

Preston Guillot
Preston Guillot

Reputation: 6724

You can achieve everything @Vadim Martynov's answer does with an additional type parameter and additional type constraints, and still receive compile-time verification.

public void Foo<T1, T2>() where T1 : IFoo 
                          where T2 : T1, new()
{
    var bar = (T1)new T2();
    //Do stuff
}

Upvotes: 0

Vadim Martynov
Vadim Martynov

Reputation: 8892

It's strange that Class<? extends SomeInterface> and not implements it. But it's not necessary for our case. addSpecificImplementation takes a Type of class that should be derived from SomeInterface and have a parameterless constructor.

Next code is not actually the same with the original because it can throw a runtime error instead of Java code which will not compiled with same constrains but it maximally repeats the concept of Java code.

At first we need to check that type is actually inherits from SomeInterface.

Next we will try to get default constructor.

And finally we can call constructor to instantiate new object.

public void AddSpecificImplementation<T>(String name, Type implClass)
    where T : SomeInterface
{
    var baseType = typeof (T);
    if (!implClass.IsAssignableFrom(baseType))
        throw new ArgumentException(String.Concat("implClass does not implement ", baseType.Name), "implClass");

    var constructor = implClass.GetConstructor(Type.EmptyTypes);
    if (constructor == null)
        throw new ArgumentException(String.Concat(baseType.Name, " has no default constructor"), "implClass");

    var myInstance = (T) constructor.Invoke(new object[0]);
    // add the instance to some data structure
}

Upvotes: 1

Related Questions