1

私は.NET用のHTTP-APIラッパーを構築しています。これには、オブジェクトにデータを設定するためのメソッドがたくさんあり、データをシリアル化してサーバーに送信します。6 つのデータ型が許可されています。

  • ストリング
  • 整数
  • 長いです
  • 浮く
  • ダブル
  • 日付時刻

私のデータ属性はジェネリックを使用しています:

SetAttribute<T>(string key, T value)

したがって、データを設定する一般的な方法は 1 つだけです。データ型を前述の 6 つに制限することはできないため、ランタイム チェックを使用し、間違ったデータ型が使用されている場合は例外をスローします。

ここで私の問題: SetAttribute の 2 つのバージョンがあります。1 つは (T 型の) 単一の値を取り、もう 1 つは (IEnumerable<T> 型の) 複数の値を取ります。問題は、プログラマーがこのラッパーを使用し、型パラメーターを指定しない場合、ランタイムが使用するメソッドを推測することです。たとえば、次のようになります。

SetAttribute("testkey","thing,anotherthing,athirdthing".Split(','))

これはデフォルトで単一値メソッドになり、T は String[] です。もちろん、String[] は有効な型ではないため、メソッドは例外をキャストします。指定する場合:

SetAttribute<string>("testkey","thing,anotherThing,aThirdThing".Split(','))

ランタイムは正しいメソッド (複数値) を選択し、T は文字列であるため、例外はキャストされません。

私の質問: 型パラメーターが必須であり、明示的に定義する必要があるように、メソッドにラベルを付けるにはどうすればよいですか? または、実行時にこれを検出して、自分でマルチメソッドにリダイレクトする必要がありますか?

4

4 に答える 4

2

わかりました。これは元々上記のコメントでした。元の質問に必ずしも答えるわけではありませんが、別のアプローチを提案しているからです。

この場合、パブリックジェネリックSetAttributeを使用することは必ずしも良い考えではありません。

型は非常に制約されているため、おそらくオーバーロードを記述して、エラーを実行時からコンパイル時に移動する必要があります。それはまたあなたが別の6つのオーバーロードで等を取ることを可能にしIEnumerable<string>そしてあなたが抱えている問題を完全に排除するでしょう。

いつでもプライベートジェネリックを使用してSetAttributeを実装し、各オーバーロードからそれを呼び出すだけで、重複を取り除くことができます。

また、型はコンパイラによってすでに制約されているため、ランタイムチェックの必要性も多かれ少なかれ排除されます。

于 2012-09-25T11:04:04.230 に答える
2

パラメーターの型を指定すると、コンパイラはオーバーロードから最適な一致を見つけます。にキャストするstring[]と、IEnumerable<string>おそらく期待どおりに機能することがわかります。これは、それらのパラメーターを正確に持つメソッドが最も一致するためです。ただし、 を受け取るメソッドがないstring[]ため、パラメーターとして 1 つを指定すると、コンパイラーは可能な限り最善の推測を行います。

オーバーロードではなく、別々に名前を付けた 2 つのメソッドを使用します。そうしないと、この問題が発生しやすくなります。または、@Joachim が示唆するように、6 つの個別のオーバーロードがあります。

于 2012-09-25T10:46:00.100 に答える
0

より良い解決策は、渡された値が他のすべてに失敗した後にIEnumerableであるかどうかをテストし、そうである場合はそのように扱うことです。(私はあなたがすでにIEnumerableを7番目のケースとして扱っていると想像します)。

于 2012-09-25T10:33:21.967 に答える
0

1 つの解決策は、元のメソッドを 6 つの非ジェネリック オーバーロードに分割し、コレクションに別のジェネリック オーバーロードを追加することです。

void SetAttribute(string key, int value);
void SetAttribute(string key, string value);
// etc

// abd this takes care of collections:
void SetAttribute<T>(string key, IEnumerable<T> value);
于 2012-09-25T10:29:49.263 に答える