【问题标题】:Class System.Dynamic.DynamicObject .. Why not abstract?类 System.Dynamic.DynamicObject .. 为什么不抽象?
【发布时间】:2015-06-10 11:31:29
【问题描述】:

浏览类System.Dynamic.DynamicObject,我发现它是具体(非抽象)类,但通过使其默认构造函数protected 来防止直接创建它的实例。

那么不使用public 构造函数将其抽象化有什么意义呢?

澄清:

class Base1
{
    protected Base1() // protected constructor, concrete class
    {
    }
}
class Derived1 : Base1
{
    public Derived1() : base()
    {
    }
}

abstract class Base2
{
    public Base2() // public constructor, abstract class
    {
    }
}
class Derived2 : Base2
{
    public Derived2() : base()
    {
    }
}

【问题讨论】:

  • 这是一个很好的问题伙伴。我希望有人能尽快回答这个问题,因为我自己也很想知道!一开始,我要告诉你,这可能是因为只有孩子才能访问具体对象,但抽象类应该可以解决问题
  • 嗯,它没有任何抽象方法。您只需要使用abstract 关键字来启用抽象方法,那么也许他们只是在具有抽象方法的抽象类上使用abstract
  • C# 完全允许您在没有任何 abstract 成员的情况下声明 abstract
  • 关键字abstract 不是用来限制对构造函数的访问,我想这是重点。类不是抽象的,但作者决定限制访问

标签: c# .net


【解决方案1】:

使用受保护的构造函数,这是可能的:

public class MyClass
{
    protected MyClass() { }

    public static MyClass GetInstance()
    {
        return new MyClass();
    }
}    

public class MyDerivedClass : MyClass
{
}

public static void Main()
{
    var myInstance = MyClass.GetInstance();
    var myDerivedInstance = new MyDerivedClass();

    var constructor = typeof(MyClass).GetConstructor(
                BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public,
                null,
                Type.EmptyTypes,
                null);

    var instanceFromReflection = (MyClass) constructor.Invoke();
}

MyClass.GetInstance()(编译器错误return new MyClass();)和反射类型(运行时错误System.MemberAccessException: Cannot create an instance of MyClass because it is an abstract class.)都不能实例化抽象MyClass

【讨论】:

  • 没什么新鲜的,在 cmets 中与@Desolator 讨论过。
  • 当然,但是 cmets 中的讨论是没有答案的,尤其是如果 cmets 被折叠...
【解决方案2】:

有评论说明

    /// <summary>
    /// Enables derived types to initialize a new instance of the <see cref="T:System.Dynamic.DynamicObject"/> type.
    /// </summary>
    [__DynamicallyInvokable]
    [TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")]
    protected DynamicObject()
    {
    }

它被用来创建System.Dynamic.DynamicObject类型的对象

【讨论】:

  • 起初我认为“这太愚蠢了,显然你可以这样做”,但这实际上可能是原因 - 如果你需要在某处传递DynamicObject,但实际上并不想要任何实现(例如某种 null-DynamicObject)。省去创建不必要的class NullDynamicObject : DynamicObject {} 的麻烦。
  • @Luaan 我认为你的评论如果是一个答案应该很好!
  • @Daniel 您的回答只是问题本身,没有添加任何有价值的信息。
  • @Desolator 我不同意。防止直接创建存在问题,而从派生类创建则没有任何问题,如果您将类抽象化,您将无法再这样做。
  • 我没听懂?如果我有一个 abstract classpublic 构造函数(或者即使没有声明构造函数,只需让它使用默认构造函数),我也可以这样做。 (即我也不能直接创建)
猜你喜欢
  • 1970-01-01
  • 2023-03-02
  • 1970-01-01
  • 1970-01-01
  • 2014-06-24
  • 1970-01-01
  • 2012-07-04
  • 1970-01-01
  • 2013-09-21
相关资源
最近更新 更多