简体   繁体   中英

Dynamically create base class or inherited class

Title may not say what exactly I am trying to do. I am not sure if this is even possible, but maybe there is a workaround. The code below is only to try to show what I want to achieve, I know this is wrong. Is it possible to create base class or inherited class at runtime? Or achieve the goal somehow else? I hope you will get the main idea from code. If not, I'll try to explain more.

public class BaseClass {
    public int baseNumber {get; set;};
}

public class DerivecClass : BaseClass {
    public int derivedNumber {get; set;};
}

public BaseClass Foo(bool derived) {
    var classInstance;

    if (derived) {
       classInstance = new DerivedClass();
    } else {
       classInstance = new BaseClass();
    }

    classInstance.baseNumber = 1234;

    if (derived) {
        classInstance.derivedNumber = 4321;
    }
    return classInstance;
}

You can't "rebase" a class at runtime (and implicitly all the classes subclass another class or System.Object (that is another class :-) )

You can create at runtime new dynamic classes through the System.Reflection.Emit namespace. You need to use the TypeBuilder class. This new classes can subclass nearly any class that isn't sealed and that doesn't have a private / internal constructor (there are some special exceptions)

If you want a simple Factory Pattern, then that is easy:

public class BaseClass
{
    public int baseNumber { get; set; }

    // So that BaseClass can't be created by other code through
    // the new BaseClass()
    protected BaseClass()
    {
    }

    public static BaseClass Create(bool derived)
    {
        BaseClass classInstance;

        if (derived)
        {
            classInstance = new DerivedClass();
        }
        else
        {
            classInstance = new BaseClass();
        }

        classInstance.baseNumber = 1234;

        if (derived)
        {
            ((DerivedClass)classInstance).derivedNumber = 4321;
        }

        return classInstance;
    }
}

public class DerivedClass : BaseClass
{
    public int derivedNumber { get; set; }

    // So that DerivedClass can't be created by other code through
    // the new DerivedClass()
    protected DerivedClass()
    {
    }
}

This pattern, nearly exactly as written, is used by XmlReader.Create(String, XmlReaderSettings)

Is it possible to create base class or inherited class at runtime?

Not with a constructor, but you could use a static factory method:

public static BaseClass Create (bool derived) {
    BaseClass classInstance;

    if (derived) {
       classInstance = new DerivedClass();
    } else {
       classInstance = new BaseClass();
    }

    classInstance.baseNumber = 1234;

    if (derived) {
        ((DerivedClass)classInstance).derivedNumber = 4321;
    }

    return classInstance;
}

Note that the code could be simplified somewhat (using initializers, removing casts, etc.) but this is as close to your original example as I could get.

Just to add to my Factory Pattern comment, you would have something like the following:

Classes:

public abstract class BaseClass
{
    public int BaseNumber {get; set;}
}

public class DerivedClassA : BaseClass
{
    public DerivedClassA()
    {
        BaseNumber = 1234;
    }
}

public class DerivedClassB : BaseClass
{
    public DerivedClassB()
    {
        BaseNumber = 4321;
    }
}

Factory:

public class ClassFactory
{
    // I'd use an Enum parameter rather than a string, but you get the idea
    public static BaseClass GetClass(string classType)
    {
        if classType.Equals("A")
            return new DerivedClassA();
        else
            return new DerivedClassB();
    }
}

Calling code:

 BaseClass class = ClassFactory.GetClass("A");

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