28

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

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

   public BaseClass(int someValue) {}

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

而且,我的代理类似于:

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

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

4

13 回答 13

65

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

在您继续之前,请确保您想以这种方式进行操作。99% 的情况下这是错误的解决方案。

这就是你的做法:

FormatterServices.GetUninitializedObject(typeof(MyClass));

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

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

于 2008-10-01T22:20:24.817 回答
26

如果没有显式调用基类中的任何构造函数,则将隐式调用无参数构造函数。没有办法解决它,如果没有调用构造函数,就无法实例化一个类。

于 2008-10-01T19:35:06.977 回答
6

必须调用至少 1 个 ctor。我看到的唯一解决办法就是收容。将类放在内部或引用其他类。

于 2008-10-01T19:34:52.080 回答
5

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

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
   }
} 
于 2008-10-01T19:38:27.860 回答
5

如果您想要调用两个基类构造函数中的任何一个,则无法执行此操作。

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

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

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

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

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

于 2008-10-01T19:53:46.323 回答
1

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

于 2008-10-01T19:35:12.547 回答
1

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

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

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

于 2008-10-01T19:35:32.857 回答
0

我最终做了这样的事情:

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

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

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

于 2008-10-01T19:58:29.357 回答
0

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

于 2011-11-21T11:37:24.410 回答
0

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

这是我的类构造函数:

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

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

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

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

于 2018-03-29T20:11:24.543 回答
0

可以在不调用无参数构造函数的情况下创建对象(参见上面的答案)。但是我使用这样的代码来创建一个基类和一个继承类,在其中我可以选择是否执行基类的init。

public class MyClass_Base
{
    public MyClass_Base() 
    {
        /// Don't call the InitClass() when the object is inherited
        /// !!! CAUTION: The inherited constructor must call InitClass() itself when init is needed !!!
        if (this.GetType().IsSubclassOf(typeof(MyClass_Base)) == false)
        {
            this.InitClass();
        }
    }

    protected void InitClass()
    {
        // The init stuff
    }
}


public class MyClass : MyClass_Base
{
    public MyClass(bool callBaseClassInit)
    {
        if(callBaseClassInit == true)
            base.InitClass();
    }
}
于 2019-07-15T06:17:18.410 回答
0

这是我对问题的解决方案

using System;

public class Program
{
    public static void Main()
    {
        Console.WriteLine(new Child().Test);
    }

    public class Child : Parent {
        public Child() : base(false) {
            //No Parent Constructor called
        }
    }
    public class Parent {
        public int Test {get;set;}
        public Parent()
        {
            Test = 5;
        }
        public Parent(bool NoBase){
            //Don't do anything
        }
    }
}

一个简单优雅的解决方案。您可以根据需要进行更改。

于 2019-10-01T07:42:29.987 回答
0

我的另一个简单解决方案:

class parent
{
    public parent()
    {
        //code for all children

        if (this.GetType() == typeof(child1))
        {
            //code only for objects of class "child1"
        }
        else
        {
            //code for objects of other child classes
        }
    }
}

class child1 : parent
{
    public child1()
    {}
}

// class child2: parent ... child3 : parent ... e.t.c
于 2021-01-16T18:16:18.887 回答