【问题标题】:Why can't we use a constructor with parameter in derived classes为什么我们不能在派生类中使用带参数的构造函数
【发布时间】:2012-08-23 10:21:41
【问题描述】:

为什么这不可能? 使用构造函数参数实例化“DerivedClass”时出现以下编译器错误:

'GenericParameterizedConstructor.DerivedClass' 不包含带 1 个参数的构造函数

但是调用一个非常相似的方法是可行的。

为什么?

class Program
{
    static void Main(string[] args)
    {
        // This one produces a compile error 
        // DerivedClass cls = new DerivedClass("Some value");

        // This one works;
        DerivedClass cls2 = new DerivedClass();
        cls2.SomeMethod("Some value");
    }
}


public class BaseClass<T>
{
    internal T Value;

    public BaseClass()
    {
    }

    public BaseClass(T value)
    {
        this.Value = value;
    }

    public void SomeMethod(T value)
    {
        this.Value = value;
    }
}

public class DerivedClass : BaseClass<String>
{
}

【问题讨论】:

    标签: c# generics parameters constructor derived-class


    【解决方案1】:

    如果有一种方法可以指示编译器为特定的派生类自动生成精确模仿和包装所有基类的构造函数,这有时会很有帮助。但是,默认情况下会发生这种行为是有问题的。许多派生类希望在创建其类型的实例时调用它们的某些代码。假设一个父类型有两个构造函数:

    父类型(int foo){...} 父类型(字符串 foo){...}

    派生类型有一个:

    派生类型(字符串 foo){...}

    new derivedType(7);应该是什么效果?编译器会知道如何创建一个new baseType(7);,但如果它创建一个新的“空白”派生类型对象,然后简单地调用父类型构造函数,结果将是一个从未运行过任何@987654324 的derivedType 对象@的构造代码。虽然有些课程对此没有任何问题(对于此类课程,前面提到的假设功能会有所帮助),但很多课程会。

    顺便说一句,受保护的构造函数会出现一个有点相关的问题。在至少包括当前版本的 C# 在内的某些 .net 语言中,如果非抽象类型 Foo 定义了受保护的构造函数,则该构造函数只能用于创建派生类型的实例。在其他语言中,包括当前的 vb.net,派生类型中的代码可以调用基类型的受保护构造函数来创建新的基类型实例。

    【讨论】:

      【解决方案2】:

      派生类需要暴露构造函数

      public class DerivedClass : BaseClass<String>
      {
          public DerivedClass(string str) :base(str) {}
      }
      

      【讨论】:

        【解决方案3】:

        构造函数不是继承的——就这么简单。 DerivedClass 包含一个构造函数 - 编译器默认提供的公共无参数构造函数,因为您没有指定任何构造函数。

        请注意,这与泛型无关。如果BaseClass 不是通用的,你会看到同样的事情。

        DerivedClass提供构造函数很容易:

        public class DerivedClass : BaseClass<String>
        {
            public DerivedClass() : base()
            {
            }
        
            public DerivedClass(string value) : base(value)
            {
            }
        }
        

        【讨论】:

        • 谢谢。你说的对。误导我的是,在实例化 DerivedClass 时总是调用 Base 类的无参数构造函数 - 即使 DerivedClass 中有无参数构造函数。
        猜你喜欢
        • 2011-02-08
        • 2020-03-06
        • 1970-01-01
        • 2016-03-08
        • 2023-03-10
        • 1970-01-01
        • 2020-07-02
        • 2013-10-28
        • 2017-12-18
        相关资源
        最近更新 更多