3

私はジェネリッククラスを持っています。2 つのコンストラクターがあります。これらは私の組織のコードベースで広く使用されています。

class MyClass<T> {
  MyClass() { ... }
  MyClass(T defaultValue) { ... }
}

いくつかの機能を追加したいが、下位互換性を維持したい。そこで、各コンストラクターに新しいブール値のオプション パラメーターを導入したいと思います。

class MyClass<T> {
  MyClass(bool someFlag = false) { ... }
  MyClass(T defaultValue, bool someFlag = false) { ... }
}

ただし、 T がブール値であり、デフォルト値が渡される使用法がすでに山ほどあります。

class Usage {
  MyClass<bool> Booly = new MyClass<bool>(false);
}

現在、オーバーロード優先の法則に従ってsomeFlag、型付きメソッドは「よく知っている」ため、コンパイラはそのようなコンストラクターの使用をすべてオーバーロードを受け入れるオーバーロードに結び付けています。ほとんどの場合、これは完全に理にかなっていますが、これは明らかに私の下位互換性を壊しています。

私の質問は簡単です:オーバーロード設定のデフォルトの法則をオーバーライドし、古いジェネリック オーバーロードを優先するものとして定義する言語機能はありますか?

もちろん、この設計の欠点は、(パラメーターのみで) 最初のオーバーロードを呼び出したいときはいつでも、someFlagC# 4 仕様に従って名前付きパラメーターを指定する必要があることです。

他のデザインの提案も大歓迎ですが、まず私の質問に答えてみてください :)。

4

2 に答える 2

1

一般に?いいえ。

特定の...「回避策」...あなたの場合はどれが受け入れられるでしょうか? オプションのパラメータを abool?ではなく a にしboolます。

new MyClass<bool>(false)あなたのオーバーロードを呼び出しますdefaultValue

new MyClass<bool>(someFlag: false)他のオーバーロードを呼び出します。

new MyClass<bool?>(false)つまり、既存の呼び出しがある場合は、代わりにそれらが変更されます。

フラグをブール値にしないようにするためのクラスを作成することで、これを克服できます。

public struct FakeBool
{
    private readonly bool val;
    private FakeBool(bool val) { this.val = val; }
    public static implicit operator bool(FakeBool f) { return f.val; }
    public static implicit operator FakeBool(bool f) { return new FakeBool(f); }
}

public MyClass(FakeBool someFlag = default(FakeBool)) { ... }
public MyClass(T defaultValue, FakeBool someFlag = default(FakeBool)) { ... }

var b2 = new MyClass<bool>(true);            // calls two-argument constructor
var b1 = new MyClass<bool>(someFlag: true); // calls one-argument constructor

しかし、これはばかげています。(また、デフォルト値のtrueを取得する方法がわかりません。アイデアはありますか?)

于 2012-10-03T15:02:47.007 に答える
0

各コンストラクターから呼び出すことができる型メソッドを使用できると仮定するとInitialize()、最善の策は 3 つのコンストラクターを使用することです。

MyClass() { Initialize(null, false); }
MyClass(T default, bool someFlag = false) { Initialize(default, someFlag); }
MyClass(bool someFlag)
{
   if (typeof(T) == typeof(bool))  Initialize(someFlag, false);
   else Initialize(null, someFlag);
}

private Initialize(T default, bool someFlag)
{ 
   // Do whatever
}
于 2012-10-05T13:54:49.097 に答える