3

大家好,问题是这样的:

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

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

public class Descendant : BaseClass
{
   // no constructors
}

我试图在 Descendant 类上调用Activator.CreateInstance ,但没有找到构造函数。

我需要在 Descentant 类上明确定义它吗?

我使用的绑定是这些:BindingFlags.Instance | BindingFlags.NonPublic

注意 1:我在现实中调用 AppDomain.CreateInstanceAndUnwrap(),如果它应该有一些影响的话。

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

注意 2:如果我在 Descendant 类中明确定义受保护的构造函数,那么它可以工作,但如果可能的话,我想避免这种情况。

4

2 回答 2

4

您不能使用 Activator.CreateInstance,但在完全信任环境中,您应该能够通过反射直接定位和调用构造函数。

实际上,您的 Descendant 类自动提供了一个公共构造函数,该构造函数传递到基类的受保护构造函数。这应该可以正常工作:

Activator.CreateInstance(typeof(Descendant))

好的,现在我意识到您正在尝试调用非默认构造函数。不幸的是,这根本是不允许的。直接在基类上调用构造函数是行不通的,因为基类是抽象的。您需要在后代类上有一个构造函数(自动生成或显式定义)才能构造对象。

您可以在 Descendant 类上创建一个传递构造函数,但您的评论听起来像是您试图避免强制实现者在其构造函数中传递一个值。您可能真正想要的是在构造对象后可以调用的初始化方法:

// 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
    }
}
于 2012-04-10T22:33:00.700 回答
1

您在这里似乎想要的是构建器模式,而不是构造器。这很简单——你定义一个类(带有默认构造函数)来“构建”你想要的类。像这样的东西(注意:前面的未经测试的代码):

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();
于 2012-04-10T23:03:24.643 回答