C# 如何继承构造函数?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/223058/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-03 18:49:20  来源:igfitidea点击:

How to inherit constructors?

c#inheritanceconstructor

提问by Ian Boyd

Imaginea base class with many constructors and a virtual method

想象一个有许多构造函数和一个虚方法的基类

public class Foo
{
   ...
   public Foo() {...}
   public Foo(int i) {...}
   ...
   public virtual void SomethingElse() {...}
   ...
}

and now i want to create a descendant class that overrides the virtual method:

现在我想创建一个覆盖虚方法的后代类:

public class Bar : Foo 
{
   public override void SomethingElse() {...}
}

And another descendant that does some more stuff:

另一个后代做了更多的事情:

public class Bah : Bar
{
   public void DoMoreStuff() {...}
}

Do i really have to copy all constructors from Foo into Bar and Bah? And then if i change a constructor signature in Foo, do i have to update it in Bar and Bah?

我真的必须将所有构造函数从 Foo 复制到 Bar 和 Bah 中吗?然后,如果我在 Foo 中更改构造函数签名,是否必须在 Bar 和 Bah 中更新它?

Is there no way to inherit constructors? Is there no way to encourage code reuse?

有没有办法继承构造函数?有没有办法鼓励代码重用?

采纳答案by Jeff Yates

Yes, you will have to implement the constructors that make sense for each derivation and then use the basekeyword to direct that constructor to the appropriate base class or the thiskeyword to direct a constructor to another constructor in the same class.

是的,您必须实现对每个派生都有意义的构造函数,然后使用base关键字将该构造函数定向到适当的基类,或使用this关键字将构造函数定向到同一类中的另一个构造函数。

If the compiler made assumptions about inheriting constructors, we wouldn't be able to properly determine how our objects were instantiated. In the most part, you should consider why you have so many constructors and consider reducing them to only one or two in the base class. The derived classes can then mask out some of them using constant values like nulland only expose the necessary ones through their constructors.

如果编译器对继承构造函数做出假设,我们将无法正确确定我们的对象是如何实例化的。在大多数情况下,您应该考虑为什么有这么多构造函数,并考虑将它们减少到基类中的一两个。派生类然后可以使用常量值屏蔽其中的一些,例如null,仅通过其构造函数公开必要的类。

Update

更新

In C#4 you could specify default parameter values and use named parameters to make a single constructor support multiple argument configurations rather than having one constructor per configuration.

在 C#4 中,您可以指定默认参数值并使用命名参数使单个构造函数支持多个参数配置,而不是每个配置都有一个构造函数。

回答by James Curran

Yes, you have to copy all 387 constructors. You can do some reuse by redirecting them:

是的,您必须复制所有 387 个构造函数。您可以通过重定向它们来进行一些重用:

  public Bar(int i): base(i) {}
  public Bar(int i, int j) : base(i, j) {}

but that's the best you can do.

但这是你能做的最好的事情。

回答by Kon

387 constructors?? That's your main problem. How about this instead?

387构造函数??那是你的主要问题。换这个怎么样?

public Foo(params int[] list) {...}

回答by tvanfosson

Too many constructors is a sign of a broken design. Better a class with few constructors and the ability to set properties. If you really need control over the properties, consider a factory in the same namespace and make the property setters internal. Let the factory decide how to instantiate the class and set its properties. The factory can have methods that take as many parameters as necessary to configure the object properly.

太多的构造函数是设计损坏的标志。更好的类具有很少的构造函数和设置属性的能力。如果您确实需要控制属性,请考虑在同一命名空间中的工厂并将属性设置器设为内部。让工厂决定如何实例化类并设置其属性。工厂可以有一些方法,这些方法可以根据需要使用尽可能多的参数来正确配置对象。

回答by Chris Marasti-Georg

The problem is not that Bar and Bah have to copy 387 constructors, the problem is that Foo has 387 constructors. Foo clearly does too many things - refactor quick! Also, unless you have a really good reason to have values set in the constructor (which, if you provide a parameterless constructor, you probably don't), I'd recommend using property getting/setting.

问题不在于 Bar 和 Bah 必须复制 387 个构造函数,问题在于 Foo 有 387 个构造函数。Foo 显然做了太多事情——快速重构!此外,除非您有充分的理由在构造函数中设置值(如果您提供无参数构造函数,您可能不会这样做),我建议使用属性获取/设置。

回答by C. Dragon 76

No, you don't need to copy all 387 constructors to Bar and Bah. Bar and Bah can have as many or as few constructors as you want independent of how many you define on Foo. For example, you could choose to have just one Bar constructor which constructs Foo with Foo's 212th constructor.

不,您不需要将所有 387 个构造函数都复制到 Bar 和 Bah。Bar 和 Bah 可以有任意数量的构造函数,与您在 Foo 上定义的数量无关。例如,您可以选择只使用一个 Bar 构造函数来构造 Foo 与 Foo 的第 212 个构造函数。

Yes, any constructors you change in Foo that Bar or Bah depend on will require you to modify Bar and Bah accordingly.

是的,您在 Bar 或 Bah 所依赖的 Foo 中更改的任何构造函数都将要求您相应地修改 Bar 和 Bah。

No, there is no way in .NET to inherit constructors. But you can achieve code reuse by calling a base class's constructor inside the subclass's constructor or by calling a virtual method you define (like Initialize()).

不,.NET 中无法继承构造函数。但是您可以通过在子类的构造函数中调用基类的构造函数或调用您定义的虚方法(如 Initialize())来实现代码重用。

回答by Greg D

You may be able to adapt a version of the C++ virtual constructor idiom. As far as I know, C# doesn't support covariant return types. I believe that's on many peoples' wish lists.

您也许能够改编C++ 虚拟构造函数惯用语的一个版本。据我所知,C# 不支持协变返回类型。我相信这是许多人的愿望清单。

回答by dviljoen

Don't forget that you can also redirect constructors to other constructors at the same level of inheritance:

不要忘记,您还可以将构造函数重定向到同一继承级别的其他构造函数:

public Bar(int i, int j) : this(i) { ... }
                            ^^^^^

回答by Keith

As Foois a class can you not create virtual overloaded Initialise()methods? Then they would be available to sub-classes and still extensible?

作为Foo一个类,你不能创建虚拟重载Initialise()方法吗?那么它们将可用于子类并且仍然可以扩展?

public class Foo
{
   ...
   public Foo() {...}

   public virtual void Initialise(int i) {...}
   public virtual void Initialise(int i, int i) {...}
   public virtual void Initialise(int i, int i, int i) {...}
   ... 
   public virtual void Initialise(int i, int i, ..., int i) {...}

   ...

   public virtual void SomethingElse() {...}
   ...
}

This shouldn't have a higher performance cost unless you have lots of default property values and you hit it a lot.

这不应该有更高的性能成本,除非您有很多默认属性值并且您经常使用它。

回答by Keith

Too bad we're kind of forced to tell the compiler the obvious:

太糟糕了,我们不得不告诉编译器显而易见的事情:

Subclass(): base() {}
Subclass(int x): base(x) {}
Subclass(int x,y): base(x,y) {}

I only need to do 3 constructors in 12 subclasses, so it's no big deal, but I'm not too fond of repeating that on every subclass, after being used to not having to write it for so long. I'm sure there's a valid reason for it, but I don't think I've ever encountered a problem that requires this kind of restriction.

我只需要在 12 个子类中做 3 个构造函数,所以没什么大不了的,但是我不太喜欢在每个子类上重复这一点,因为习惯了不用这么长时间写它。我确信这样做是有正当理由的,但我认为我从未遇到过需要这种限制的问题。