5

私は、.NET 4でしばらくの間、限られた方法でオプションのパラメーターを使用してきました。最近、オプションのパラメーターがどのように実装され、何かが私に夜明けを迎えたかについて考えました。

次の例を見てください。

public interface ITest
{
    void Go(string val = "Interface");
}

これを実装するための唯一の要件は、署名の最大形式をvoid Go (string val)実装することです。実際、コンパイラがそのワイヤアップを処理するため、オプションのパラメータを実装する必要はありません(ただし、オプションのパラメータを使用するオプションは使用時に使用できません)具体的なクラス)。

そうは言っても、両方の場所で機能を提供し、実装で検出できるようにするには、インターフェイスと実装の両方でオプションの宣言を実装できます。実際、生産性ツールReSharperは、インターフェースを実装するときに、このオプションの宣言を具象型に自動的にプルアップします。これは論理的なことのようです。でも...

具体的なタイプとインターフェースで異なる値を使用しないようにするにはどうすればよいですか?これは今朝、誰かがその値を変更するために入って、オーバーライド/インターフェイスの継承にそれを保持するのを忘れたかのように私の警報ベルを鳴らしました、動作はオブジェクトへのアクセス方法によって完全に異なります。これは、デバッグするのに非常にイライラする可能性があります。

このLINQpadスクリプトを試してください:

void Main()
{
    IA iface = new A();
    A cls = new A();

    iface.Go();
    cls.Go();
}

interface IA
{
    void Go(string val = "Interface");
}

class A : IA
{
    public void Go(string val = "Class") { val.Dump(); }
}

出力は次のようになります。

Interface
Class

それは私の実際の質問に私をもたらします:

質問:

具象クラスのオプションのパラメーターバリアントを使用する機能を失うことなく、これを保護する方法(ある場合)は何ですか?したがって、それはコーダーにとって検出可能/読み取り可能ですか?

誰かが以前にこの問題に遭遇したことがありますか?どのようにそれを解決しましたか?この問題がマルチ開発者の大規模なコードベースで蔓延するのを防ぐのに役立つ可能性のあるベストプラクティスはありますか?

4

2 に答える 2

3

あなたがそれをするのを妨げるものは何もありません。オプションのパラメーターを使用すると、値がメソッド呼び出しに組み込まれます。ご覧のとおり、とにコンパイルされているため、呼び出しIA.Go()A.Go()さまざまな値を指定します。 IA.Go("Interface")A.Go("Class")

それを回避する方法(実装で「デフォルト」パラメーターのみを提供することを意味します)は、オプションのパラメーターの代わりにオーバーロードを設定することです。

interface IA
{
    void Go();
    void Go(string val);
}

public class A : IA
{
    public void Go()
    {
        Go("Class");
    }
    public void Go(string val) { val.Dump(); }
}

他のいくつかのオプション:

  • その状態をチェックする単体テストを追加します。ただし、実装ごとにそれを行う必要があります。
  • カスタムコード分析ルールの作成を調査します。
于 2012-10-17T18:30:23.797 に答える
1

それはC#の性質であり、それと一緒に暮らす必要があると思います。以下の例を見てください。オプションのパラメータがなくても同じことを行います。つまり、オブジェクトへのアクセス方法によって動作が異なります。

class Program
{
    static void Main(string[] args)
    {
        IA iface = new A();
        A cls = new A();

        iface.Test();
        cls.Test();

        Console.ReadKey();
    }
}

interface IA
{
    void Test();
}

class A : IA
{
    public void Test()
    {
        Console.WriteLine("Class");
    }

    void IA.Test()
    {
        Console.WriteLine("Interface");
    }
}
于 2012-10-17T18:24:41.113 に答える