基本コンストラクターがC#の継承者によって呼び出されるのを防ぐにはどうすればよいですか?
-
03-07-2019 - |
質問
プロキシオブジェクトでラップする(記述が不十分な)基本クラスがあります。基本クラスは次のようになります。
public class BaseClass : SomeOtherBase
{
public BaseClass() {}
public BaseClass(int someValue) {}
//...more code, not important here
}
そして、私のプロキシは次のようになります:
public BaseClassProxy : BaseClass
{
public BaseClassProxy(bool fakeOut){}
}
" fakeOut"なしコンストラクターでは、基本コンストラクターが呼び出されることが期待されています。しかし、それで、私はそれが呼び出されないと予想しました。いずれにせよ、基本クラスコンストラクターを呼び出さない方法、またはこの(邪悪な)クラスを効果的にプロキシする他の方法が必要です。
解決
基本クラスのコンストラクターを明示的に呼び出さない場合、パラメーターのないコンストラクターは暗黙的に呼び出されます。それを回避する方法はありません。コンストラクタを呼び出さずにクラスをインスタンス化することはできません。
他のヒント
any インスタンスコンストラクターを呼び出さずにオブジェクトを作成する方法があります。
先に進む前に、この方法で実行することを確認してください。 99%の時間、これは間違った解決策です。
これがあなたのやり方です:
FormatterServices.GetUninitializedObject(typeof(MyClass));
オブジェクトのコンストラクタの代わりに呼び出します。コンストラクターやフィールド初期化子を呼び出すことなく、インスタンスを作成して返します。
WCFでオブジェクトを逆シリアル化すると、このメソッドを使用してオブジェクトが作成されます。これが発生すると、コンストラクターやフィールド初期化子さえ実行されません。
少なくとも1つのctorを呼び出す必要があります。私が見る唯一の方法は封じ込めです。クラスを内部に置くか、他のクラスを参照します。
2つの基本クラスコンストラクターのいずれかを呼び出さない場合、これは実行できません。
C#クラスコンストラクターは、基本クラスコンストラクターを呼び出す必要があります。明示的に呼び出さない場合、 base()が暗示されます。例では、呼び出す基本クラスコンストラクターを指定しない場合、次と同じです。
public BaseClassProxy : BaseClass
{
public BaseClassProxy() : base() { }
}
他の基本クラスコンストラクターを使用する場合は、次を使用できます。
public BaseClassProxy : BaseClass
{
public BaseClassProxy() : base(someIntValue) { }
}
どちらの方法でも、2つの のいずれかが明示的または暗黙的に呼び出されます。
コンストラクタの呼び出しを回避できるとは思わない。しかし、あなたはこのようなことをすることができます:
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) {}
最初のコンストラクタの代わりに2番目のコンストラクタを呼び出す
基本呼び出しコンストラクターがオプションではないことを恐れています。
私は結局このようなことをしました:
public class BaseClassProxy : BaseClass
{
public BaseClass BaseClass { get; private set; }
public virtual int MethodINeedToOverride(){}
public virtual string PropertyINeedToOverride() { get; protected set; }
}
これにより、基本クラスのいくつかの悪い習慣を回避できました。
コンストラクターは本来公開されています。コンストラクタを使用せず、構築に別のコンストラクタを使用してprivate.soにします。したがって、パラメータなしでインスタンスを作成し、オブジェクトインスタンスを構築するためにその関数を呼び出します。
大丈夫、ここに、あるクラスが別のクラスのコンストラクターを継承するという問題のい解決策がありますが、一部のクラスの動作を許可したくありませんでした。私のクラスではこれですが、ここにあります:
クラスコンストラクタは次のとおりです:
public MyClass();
{
throw new Exception("Error: Must call constructor with parameters.");
}
[OK]をクリックすると、itいものであると警告されました。苦情はご遠慮ください!
パラメーターなしで継承されたベースコンストラクターを許可せずに、少なくともメインコンストラクターから最小限のパラメーターを強制したい
また、コンストラクタを作成し、その後に:base()を付けないと、ベースクラスコンストラクタを呼び出さないと思います。そして、すべてのコンストラクタを作成する場合基本クラスで、メインクラスでそれらと同じ正確なパラメーターを提供しますが、それは通過しません。しかし、基本クラスに多くのコンストラクターがある場合、これは面倒です!