简体   繁体   中英

C# function that returns type according to a parameter

I would like to create a function that returns new object according to the parameter, for example:

Base Class:

class BaseClass
{
    public int x;
}

Class One:

class TestClassOne: BaseClass
{        
    public TestClassOne()
    {
        this.x = 1;
    }   
}

Class Two:

class TestClassTwo: BaseClass
{
    public TestClassOne()
    {
        this.x = 2;
    }   
}

Main:

static void Main(string[] args)
{
    BaseClass bc = GetConstructor("TestClassOne");
    Console.WriteLine(bc.x); //Prints 1
}

static BaseClass GetConstructor(string className)
{
    if(className.Equals("TestClassOne"))
    {
        return new TestClassOne();
    }
    else if(className.Equals("TestClassTwo"))
    {
        return new TestClassTwo();
    }
    return null;
} 

The code I wrote works well, the problem is when I will have a lot of derived classes like TestClassThree, TestClassFour... TestClassThousand. How can I make a function that returns the correct constructor without if else or switch case and etc? I think that reflection would be a good option but I'm not really sure how to use it. Thanks!

It would be best if you can use a generic method, lik in the answer of René, but you are using strings, so it doesn't seem so.

There are two steps:

  • Get the correct type;
  • Create an instance.

This is the minimal code necessary:

Type t = Assembly.GetExecutingAssembly().GetType("SO.BaseClass");

object o = Activator.CreateInstance(t);

As you can see, you need to know the assembly and the namespace of the type, or you will have to do some fuzzy matching on either.

I would offer a word of caution with your implementation. What you are attempting to do is called a factory. Considering the fact that you are adding a dependency for a base class, you will be limited to only allowing constructors with that base class. If you ever needed certain classes to have a different base class but be offered through the same method, you would need to share an interface instead. Like others have suggested, you can use generics. Here is an example without generics:

public static IMyInterface GetMatchingClass(string className)
    {
        Type t = Type.GetType(className);
        return (IMyInterface)Activator.CreateInstance(t);
    }

As long as the classes you return implement the given interface, all is peachy.

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