Question

Greetings fellow members, the situation in question is such:

public abstract class BaseClass
{
    protected BaseClass()
    {
        // some logic here
    }

    protected BaseClass(Object parameter) : this()
    {
        // some more logic
    }
}

public class Descendant : BaseClass
{
   // no constructors
}

I'm trying to call Activator.CreateInstance on the Descendant class, but no constructor is found.

Do I need to explicitly define it on the Descentant class?

The bindings I've used are these: BindingFlags.Instance | BindingFlags.NonPublic

Note 1: I'm calling AppDomain.CreateInstanceAndUnwrap() in reality, if it should have some influence.

 domain.CreateInstanceAndUnwrap(path, typeName, false, BindingFlags.Instance |
     BindingFlags.NonPublic, null, new[] { parameter }, null, null);

Note 2: If I explicitly define the protected constructor in the Descendant class then it works, but I'd like to avoid this if possible.

Was it helpful?

Solution

You cannot use Activator.CreateInstance, but in Full Trust environments you should be able to locate and call the constructor directly by reflection.

Actually, your Descendant class automatically provides a public constructor that does a pass-through to the protected constructor of the base class. This should work just fine:

Activator.CreateInstance(typeof(Descendant))

Okay, so now I realize that you're trying to invoke the non-default constructor. Unfortunately for you, this is simply not allowed. Invoking the constructor on the base class directly won't work because the base class is abstract. You need to have a constructor (either auto-generated or explicitly defined) on the descendant class in order to construct an object.

You could create a pass-through constructor on the Descendant class, but your comments make it sound like you're trying to avoid forcing implementers to pass a value through in their constructor. What you probably really want is an initialization method that you can call after constructing the object:

// Define other methods and classes here
public abstract class BaseClass
{
    protected BaseClass()
    {
        // some logic here
    }

    protected Object Parameter {get; private set;}    

    public virtual void Initialize(Object parameter)
    {
        Parameter = _parameter;
        // some more logic
    }
}

OTHER TIPS

What it seems like you want here is the builder pattern, rather than constructors. It's quite simple- you define a class (with a default constructor) that "builds" the class you want. Something like this (note: untested code ahead):

public abstract class BaseBuildable : MarshalByRefObject {
   public String Foo { get; internal set; }
}

public class DerivedBuildable : BaseBuildable { }

public class BuildableBuilder : MarshalByRefObject {
   private String _foo;
   public BuildableBuilder WithFoo(String foo) { _foo = foo; return this; }
   public TBuildable Build<TBuildable>() where TBuildable : BaseBuildable, new() {
       return new TBuildable { Foo = _foo; }
   }
}

// Used so:
var builder = domain.CreateInstanceAndUnwrap(.. // yadda yadda, you want a BuildableBuilder
var buildable = builder.WithFoo("Foo, yo").Build();
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top