TL;DR: (タイトルからわかるように) List<T>
1 回の変換で "からジェネリック引数を暗黙的に削除することはできますか?
今日、ある友人List<T>
から、 a を非ジェネリック ラッパーに暗黙的に変換できるかどうか尋ねられました。
var list = new List<_some_type_>();
ObjectResult result = list;
メソッドは次のようになります。
public static implicit operator ObjectResult(List<T> list) { ... }
明らかに、T
here は定義されておらず、暗黙の演算子のメソッド名は型名です。したがって、型が実際にジェネリックでない限り、メソッド名にジェネリック パラメータを含めることはできません。
class ObjectResult<T> { ... }
それ以外の
class ObjectResult { ... }
ユーザー定義の変換に関する制約は次のとおりです (不足しているものはありますか?)。
- 基本型との間で変換できません
- インターフェイスとの間で変換できません。
- 2 つのタイプのいずれかに囲まれた変換を行う必要があります。
難しいList<T>
理由:
List<T>
の唯一の派生はObject
;から来ます。したがって、から直接変換する必要がありますList<T>
List<T>
インターフェースのみを持ち、再び、から直接でなければなりませんList<T>
List<T>
、明らかに、フレームワークでコンパイルされているため、ラッパーからのものでなければなりません
私は、変換できる仲介者がいる 2 段階の解決策を考えました (一方、仲介者は のみでList<T>
ありObject
、ルール #1 により、それはオプションではありません)。
public class ObjectResult
{
public static implicit operator ObjectResult(WrapperBase arg) { ... }
}
public class WrapperBase { }
public class ObjectResultWrapper<T> : WrapperBase
{
public static implicit operator ObjectResultWrapper<T>(List<T> arg) { ... }
}
次に、呼び出しコードは次のようになります。
var list = new List<int>();
ObjectResultWrapper<int> wrap = list;
ObjectResult result = wrap;
これは問題を実際に解決するものではありません。暗黙的にドロップするのは単なる回避策T
です (ただし、1 つではなく 2 つのステップで)。この時点では、ユーザー定義の変換を使用せずに、ヘルパー メソッドを使用する方が簡単です。
一般的な引数を暗黙のうちに削除するという目標に反対する引数があるかもしれません.なぜこれが重要であると彼が感じているのか、私には他に何もありません. これは単に学術的な問題だと考えてください。