是否可以使用受保护的构造函数创建对象的实例

本文关键字:构造函数 实例 创建对象 受保护 可以使 是否 | 更新日期: 2023-09-27 18:30:45

各位成员问候,情况是这样的:

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 类中显式定义受保护的构造函数,那么它可以工作,但如果可能的话,我想避免这种情况。

是否可以使用受保护的构造函数创建对象的实例

您不能使用 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
    }
}

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

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();