5

呼び出すインターフェイスとして API をIFoo定義しており、メソッドを定義したいBar()

このメソッドBar()は、1 つの必須引数と、任意の数の他の引数を取ります。これらの他の引数の解釈は、実装者次第です。IFoo

このシナリオでは、例を使用paramsまたは使用してインターフェースを定義する方が適切ですか?Dictionary<String, Object>

public interface IFoo
{
   bool Bar(String id, params Object[] params);
}

または

public interface IFoo
{
   bool Bar(String id, Dictionary<String, Object> params);
}

前者はユーザーにとって呼び出しが簡単なようですが、前者では実装が適切に解釈するために特定の順序でパラメーターを指定する必要があるため、後者はその意図がより明確です。後者では本質的に名前付きパラメーターを実行します。

だから質問:

  • どのフォームを使用する必要がありますか (そしてその理由は?) - これらのうちの 1 つは他のものよりもベスト プラクティスと見なされますか?
  • 私が知っておくべき特定のスタイルと他のスタイルの利点はありますか? これらの 1 つは、コードの臭いと見なされますか?
  • 別の/より良い方法で同じことを達成する代替パターンはありますか?

記録のために、.Net 4.0 の名前付きパラメーターを認識していますが、このコードは .Net 3.5 でコンパイル可能である必要があるため、.Net 4.0 以降の機能は使用できません。

編集

IFoo誰かが尋ねたので、 my メソッドとBar()メソッドが実際に何を表しているかについての詳細を追加するだけです。

IFoo一部のストレージ サブシステムを表し、Bar()実際には作成操作です。ストレージ サブシステムによってはBar()、ID 以外のパラメーターが必要ない場合と、多くのパラメーターが必要な場合があります。

編集 2

したがって、@ Kirk Wollのコメントと@ Fernandoの回答に応じて、詳細情報を以下に示します.

IFoo.Bar()このインターフェイスはオープン ソース フレームワークの一部です。サード パーティの開発者が実装IFooし、エンド ユーザーがその特定のインスタンスを呼び出すことにIFooなります。その目的は、ユーザーがストレージ サブシステム間でアプリケーションを簡単に移行できるようにすることです。人間的に可能。

最も単純なケースでは、基礎となるストレージ サブシステムにはストアの形式が 1 つしかないため、ID 以外のパラメーターは必要ありません。複雑なケースでは、ストレージ サブシステムが複数のタイプのストアを許可する場合があり、ストアの各タイプが任意の複雑な構成パラメーターのセット (インデックス サイズ、永続性、トランザクション動作、インデックス作成戦略、セキュリティ、ACL の考慮事項など) を許可する場合があります。

私は@Fernandoに同意しますが、おそらくもっとポリモーフィックなものが理にかなっているかもしれません。おそらくポリモーフィズムとジェネリックと型の制限を組み合わせたものが最適かもしれません。

public interface IFoo
{
  bool Bar<T>(T parameters) where T : IBarConfig;
}

public interface IBarConfig
{
  String ID { get; set; }
}

次に、次のような実装を使用します。

public class MyFoo
{
  bool Bar<T>(T config) where T : MyBarConfig
  {
    //Implementation
  }
}

public class MyBarConfig : IBarConfig
{
  public String ID { get; set; }

  public long IndexSegmentSize { get; set; }

  //Etc...
}

これは私の頭の中から外れているので、実装するインターフェイスとは異なる型制限で定義Bar()することが実際に合法であるかどうかはわかりませんか?MyFoo

4

5 に答える 5

4

params コレクション/配列からオブジェクトを検索または取得できるようにする必要があるかどうかを判断する必要があります。

を使用する場合 Object[] params、オブジェクトにはインデックスが作成されません。アイテムを見つけるには、コレクション全体を反復処理する必要があります (そのキーによって)。

を使用するDictionary<String, Object>場合、オブジェクトはキーによってインデックス付けされ、キーによって常に簡単に検索/クエリできます。

必要に応じて、アプローチを決定する必要があります。

ディクショナリは検索が高速ですが、インデックスを作成するためのオーバーヘッドがあります。

于 2012-07-07T00:05:34.113 に答える
2

params は、インラインで記述する必要がある場合、Dictionary と比較してコードの記述/読み取りが容易になります。つまり、String.Format への呼び出しごとに辞書を構築するイメージング - コードは読み取り不能になります。一方、パラメータの辞書がすでにある場合は、それを使用しても構いません。

IEnumerableAPI を再検討し、引数として、またはそれ以上を受け入れることができるかどうかを確認することをお勧めしIEnumerable<T>ます。残念ながら、サンプルのこのような一般的な IFoo 名では、そのようなアプローチが機能するかどうかを確認することはできません。

于 2012-07-07T00:19:44.103 に答える
2

辞書のアプローチには別の問題があります。タイプミスです。この問題を回避するには、キーとして使用する多くの定数を定義する必要があるでしょう。

ポリモーフィック ソリューションを採用しない理由はありません。

public interface IFoo {
    void Bar(FooData data);
}

public abstract class FooData {
     public int Id {get;set;}
}

public class MyFooData1 : FooData {
    public string SomeProperty {get;set;} 
    //...
}

public class MyFoo : IFoo {
    public void Bar(FooData data) {
        var myData = (MyFooData1)data;
        //...
    }
}

public class MyFooData2 : FooData {
    public int SomeOtherProperty {get;set;}
    //...
}

public class MyFoo2 : IFoo {
    public void Bar(FooData data) {
        var myData = (MyFooData2)data;
        //...
    }
}

最終的にはより小さなクラスになりますが、テストと拡張は簡単です。

アップデート

@RobVインターフェイスを実装している場合、型の制限を変更することはできませんが、型パラメーターをインターフェイス宣言に配置すると、やろうとしていることを達成できます。

public interface IFoo<T> where T : IBarConfig {
    void Bar(T parameters);
}

public class MyBarConfig: IBarConfig {
    public String ID { get; set; }
    public long IndexSegmentSize { get; set; } 
}

public class MyFoo : IFoo<MyBarConfig> {
  public void Bar(MyBarConfig config) {
    //Implementation
  }
}
于 2012-07-07T01:39:17.110 に答える
0

オプションのパラメーターに言及したという事実は、IDictionary<string,object>アプローチがより良いと私に思わせます.Net 3.5でその種のインターフェースを提供するための最良のアプローチです。object を要求して、MVC が htmlAttributes に対して行うことと同様のことを行うことができIDictionary<string,object>ます (リフレクションを使用して匿名オブジェクトを に変換します)。

私がこのparams object[]アプローチを好むシナリオは、string.format.

于 2012-07-07T01:22:10.340 に答える
0

どのフォームを使用する必要がありますか (また、その理由は?) - これらのうちの 1 つは他のものよりもベスト プラクティスと見なされますか? ---> 2 番目のものよりもエラーが発生しにくいため、2 番目のものを使用する必要があります。

代替パターンに関しては、これをより適切な方法で実装する方法が確かにあります。あなたの問題が実際に何であるか教えていただけますか?IFoo と Bar を使用する代わりに? あなたが何をしようとしているのか、そしてその理由が正確にわからない限り、他に何も提案することはできません...

于 2012-07-07T00:19:23.547 に答える