2008-10-01 5 views
16

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

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

    public BaseClass(int someValue) {} 

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

и мой прокси напоминает:

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

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

ответ

18

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

+1

Собственно, если вы прочтете мой комментарий ниже, есть способ, хотя я бы не рекомендовал его в большинстве случаев. – 2008-10-21 17:44:00

+0

Этот ответ просто неправильный. Особенно в свете другого ответа. – Kobor42 2015-03-31 08:50:16

6

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

+0

Это путь, который дает мне больше всего результатов. Благодаря! – casademora 2008-10-01 19:55:08

1

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

1

При создании BaseClassProxy объекта он должен создать экземпляр это базовый класс, так что вам нужно вызвать конструктор базового класса, что вы можете д.о.о. это выбрать Wich один позвонить, как:

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

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

4

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

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

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

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

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

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

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

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

0

Я закончил тем, что делал что-то вроде этого:

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

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

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

+2

Неявный конструктор по умолчанию, который все еще вызывает конструктор без параметров в BaseClass. – recursive 2008-12-17 17:28:20

46

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

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

Это, как вы это делаете:

FormatterServices.GetUninitializedObject(typeof(MyClass)); 

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

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

0

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

0

Это моя неряшливая первая попытка этого ответа. Проголосуйте, и я придаю этому больше внимания.

Я не уверен, чего вы пытаетесь выполнить, но похоже, что у вас отсутствуют интерфейсы. Вы можете выбрать, какие интерфейсы имеют смысл для ваших нужд. Если это так, если для тестирования вы использовали бы что-то вроде A.Fake для тестирования. Если вы предоставите более подробную информацию о том, что вы пытаетесь выполнить. Я мог бы быть более полезным.

public interface IExtractedFromSomeOtherBase{ 
    // this could also be an interface that the other base already implements. 
    /* extracted stuff here */ 
} 
public interface IBaseClass { 
    /* stuff */ 
} 
public interface IBaseClassProxy { 
    /* stuff */ 
} 
public class BaseClass : 
    SomeOtherBase, IExtractedFromSomeOtherBase, IBaseClass 
{ 
    public BaseClass() {} 

    public BaseClass(int someValue) {} 

    //...more code, not important here 
} 
and, my proxy resembles: 

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