Как я могу запретить вызов базового конструктора наследником в C#?

StackOverflow https://stackoverflow.com/questions/159296

Вопрос

У меня есть (плохо написанный) базовый класс, который я хочу обернуть в прокси-объект.Базовый класс выглядит следующим образом:

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

   public BaseClass(int someValue) {}

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

и мой прокси выглядит так:

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

Без конструктора «fakeOut» ожидается вызов базового конструктора.Однако при этом я ожидал, что его не вызовут.В любом случае мне нужен либо способ не вызывать конструкторы базового класса, либо какой-то другой способ эффективно проксировать этот (злой) класс.

Это было полезно?

Решение

Если вы не вызываете явно какой-либо конструктор в базовом классе, конструктор без параметров будет вызван неявно.Обойти это невозможно: вы не можете создать экземпляр класса без вызова конструктора.

Другие советы

Существует способ создать объект без вызова любой конструкторы экземпляров.

Прежде чем продолжить, убедитесь, что вы хотите сделать это именно так.В 99% случаев это неправильное решение.

Вот как вы это делаете:

FormatterServices.GetUninitializedObject(typeof(MyClass));

Вызовите его вместо конструктора объекта.Он создаст и вернет вам экземпляр без вызова каких-либо конструкторов или инициализаторов полей.

Когда вы десериализуете объект в WCF, он использует этот метод для создания объекта.Когда это происходит, конструкторы и даже инициализаторы полей не запускаются.

Должен быть вызван как минимум 1 актер.Единственный способ обойти это, я вижу, это сдерживание.Имейте класс внутри или ссылайтесь на другой класс.

Если то, что вы хотите, это нет вызвать любой из двух конструкторов базового класса, это невозможно сделать.

Конструкторы классов C# должны вызывать конструкторы базовых классов.Если вы не вызываете его явно, база( ) подразумевается.В вашем примере, если вы не укажете, какой конструктор базового класса вызывать, это будет то же самое, что:

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

Если вы предпочитаете использовать другой конструктор базового класса, вы можете использовать:

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

В любом случае, одно из двух воля вызываться явно или неявно.

Я не верю, что можно обойтись без вызова конструктора.Но вы могли бы сделать что-то вроде этого:

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
   }
} 

Когда вы создаете объект BaseClassProxy, ему НЕОБХОДИМО создать экземпляр его базового класса, поэтому вам нужно вызвать конструктор базового класса, что вы можете сделать, это выбрать, какой из них вызывать, например:

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

Чтобы вызвать второй конструктор вместо первого

Я боюсь, что конструктор базовых вызовов не является вариантом.

В итоге я сделал что-то вроде этого:

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

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

Это помогло мне преодолеть некоторые плохие практики базового класса.

конструкторы являются общедоступными по своей природе.не используйте конструктор, а используйте другой для создания и сделайте его частным. Таким образом, вы создадите экземпляр без параметров и вызовете эту функцию для создания экземпляра вашего объекта.

Хорошо, вот уродливое решение проблемы, когда один класс наследует конструкторы другого класса, и я не хотел, чтобы некоторые из них работали. Я надеялся избежать использования этого в своем классе, но вот оно:

Вот мой конструктор класса:

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

Хорошо, теперь вас предупредили, что это некрасиво.Никаких жалоб, пожалуйста!

Я хотел получить хотя бы минимальные параметры из моего основного конструктора, не допуская при этом унаследованный базовый конструктор без параметров.

Я также считаю, что если вы создадите конструктор и не поместите:base() после него, что он не будет вызывать конструктор базового класса. И если вы создадите конструкторы для всех конструкторов базового класса и предоставите им одинаковые параметры в основном классе, это не пройдет.Но это может быть утомительно, если в базовом классе много конструкторов!

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top