如何防止基构造函数被 C# 中的继承者调用?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/159296/
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 16:10:35  来源:igfitidea点击:

How can I prevent a base constructor from being called by an inheritor in C#?

提问by casademora

I've got a (poorly written) base class that I want to wrap in a proxy object. The base class resembles the following:

我有一个(写得不好)基类,我想将其包装在代理对象中。基类类似于以下内容:

public class BaseClass : SomeOtherBase 
{
   public BaseClass() {}

   public BaseClass(int someValue) {}

   //...more code, not important here
}

and, my proxy resembles:

而且,我的代理类似于:

public BaseClassProxy : BaseClass
{
  public BaseClassProxy(bool fakeOut){}
}

Without the "fakeOut" constructor, the base constructor is expected to be called. However, with it, I expected it to not be called. Either way, I either need a way to not call any base class constructors, or some other way to effectively proxy this (evil) class.

如果没有“fakeOut”构造函数,则预计会调用基本构造函数。但是,有了它,我希望它不会被调用。无论哪种方式,我要么需要一种不调用任何基类构造函数的方法,要么需要某种其他方法来有效地代理这个(邪恶的)类。

采纳答案by Tron

If you do not explicitly call any constructor in the base class, the parameterless constructor will be called implicitly. There's no way around it, you cannot instantiate a class without a constructor being called.

如果您没有显式调用基类中的任何构造函数,则将隐式调用无参数构造函数。没有办法解决它,你不能在没有调用构造函数的情况下实例化一个类。

回答by mattlant

At least 1 ctor has to be called. The only way around it I see is containment. Have the class inside or referencing the other class.

必须至少调用 1 个 ctor。我看到的唯一解决方法是收容。将类放在里面或引用另一个类。

回答by Jakub ?turc

I am affraid that not base calling constructor isn't option.

我恐怕不是基调用构造函数不是选项。

回答by albertein

When you create a BaseClassProxy object it NEEDS to create a instance of it's base class, so you need to call the base class constructor, what you can doo is choose wich one to call, like:

当您创建 BaseClassProxy 对象时,它需要创建其基类的实例,因此您需要调用基类构造函数,您可以选择要调用的一个,例如:

public BaseClassProxy (bool fakeOut) : base (10) {}

To call the second constructor instead of the first one

调用第二个构造函数而不是第一个

回答by Jake Pearson

I don't believe you can get around calling the constructor. But you could do something like this:

我不相信你可以绕过调用构造函数。但是你可以做这样的事情:

public class BaseClass : SomeOtherBase 
{
   public BaseClass() {}

   protected virtual void Setup()
   {
   }
}

public BaseClassProxy : BaseClass
{
   bool _fakeOut;
   protected BaseClassProxy(bool fakeOut)
   {
        _fakeOut = fakeOut;
        Setup();
   }

   public override void Setup()
   {
       if(_fakeOut)
       {
            base.Setup();
       }
       //Your other constructor code
   }
} 

回答by Lucas

If what you want is to notcall either of the two base class constructors, this cannot be done.

如果您想要的是调用两个基类构造函数中的任何一个,则无法做到这一点。

C# class constructors must call base class constructors. If you don't call one explicitly, base( )is implied. In your example, if you do not specify which base class constructor to call, it is the same as:

C# 类构造函数必须调用基类构造函数。如果你不明确地调用一个,base()是隐含的。在您的示例中,如果您未指定要调用的基类构造函数,则与以下内容相同:

public BaseClassProxy : BaseClass
{
    public BaseClassProxy() : base() { }
}

If you prefer to use the other base class constructor, you can use:

如果您更喜欢使用其他基类构造函数,则可以使用:

public BaseClassProxy : BaseClass
{
    public BaseClassProxy() : base(someIntValue) { }
}

Either way, one of the two willbe called, explicitly or implicitly.

无论哪种方式,将显式或隐式调用两者之一。

回答by casademora

I ended up doing something like this:

我最终做了这样的事情:

public class BaseClassProxy : BaseClass 
{
   public BaseClass BaseClass { get; private set; }

   public virtual int MethodINeedToOverride(){}
   public virtual string PropertyINeedToOverride() { get; protected set; }
}

This got me around some of the bad practices of the base class.

这让我了解了基类的一些不良做法。

回答by Neil

There is a way to create an object without calling anyinstance constructors.

有一种方法可以在不调用任何实例构造函数的情况下创建对象。

Before you proceed, be very sure you want to do it this way. 99% of the time this is the wrong solution.

在继续之前,请确保您要这样做。99% 的情况下这是错误的解决方案。

This is how you do it:

这是你如何做到的:

FormatterServices.GetUninitializedObject(typeof(MyClass));

Call it in place of the object's constructor. It will create and return you an instance without calling any constructors or field initializers.

调用它代替对象的构造函数。它将创建并返回一个实例而不调用任何构造函数或字段初始值设定项。

When you deserialize an object in WCF, it uses this method to create the object. When this happens, constructors and even field initializers are not run.

当您在 WCF 中反序列化对象时,它使用此方法来创建对象。发生这种情况时,构造函数甚至字段初始值设定项都不会运行。

回答by U?ur Gümü?han

constructors are public by nature. do not use a constructor and use another for construction and make it private.so you would create an instance with no paramtersand call that function for constructing your object instance.

构造函数本质上是公共的。不要使用构造函数并使用另一个构造函数并将其设为私有。因此您将创建一个没有参数的实例并调用该函数来构造您的对象实例。

回答by John Foll

All right, here is an ugly solution to the problem of one class inheriting the constructors of another class that I didn't want to allow some of them to work.I was hoping to avoid using this in my class but here it is:

好吧,这是一个类继承另一个类的构造函数的问题的丑陋解决方案,我不想让它们中的一些工作。我希望避免在我的课堂上使用它,但这里是:

Here is my class constructor:

这是我的类构造函数:

public MyClass();
{
   throw new Exception("Error: Must call constructor with parameters.");
}

OK now you were warned that it was ugly. No complaints please!

好的,现在你被警告说它很丑。请不要抱怨!

I wanted to force at least the minimal parameters from my main constructor without it allowing the inherited base constructor with no parameters.

我想至少从我的主构造函数中强制使用最少的参数,而不允许没有参数的继承基构造函数。

I also believe that if you create a constructor and do not put the : base() after it that it will not call the base class constructor.And if you create constructors for all of the ones in the base class and provide the same exact parameters for them in the main class, that it will not pass through. But this can be tedious if you have a lot of constructors in the base class!

我也相信,如果您创建一个构造函数并且不将 :base() 放在它之后,它将不会调用基类构造函数。如果您为基类中的所有构造函数创建构造函数,并在主类中为它们提供完全相同的参数,则它不会通过。但是如果基类中有很多构造函数,这可能会很乏味!