Java では、次のような「不明な」ジェネリック型によってパラメーター化された変数を宣言できます。
Foo<?> x;
C# で、この疑問符に相当する構造はありますか?
簡単な答えはノーです。C#には同等の機能はありません。
Dare ObasanjoによるJava開発者の観点からのC#からの回避策:
場合によっては、特定の型を含むデータ構造ではなく、任意の型を含むデータ構造を操作できるメソッド(たとえば、データ構造内のすべてのオブジェクトを出力するメソッド)を作成し、その利点を活用する必要があります。ジェネリックスの強い型付け。C#でこれを指定するメカニズムは、ジェネリック型推論と呼ばれる機能を介して行われますが、Javaではこれはワイルドカード型を使用して行われます。次のコードサンプルは、両方のアプローチがどのように同じ結果につながるかを示しています。
C#コード
using System;
using System.Collections;
using System.Collections.Generic;
class Test{
//Prints the contents of any generic Stack by
//using generic type inference
public static void PrintStackContents<T>(Stack<T> s){
while(s.Count != 0){
Console.WriteLine(s.Pop());
}
}
public static void Main(String[] args){
Stack<int> s2 = new Stack<int>();
s2.Push(4);
s2.Push(5);
s2.Push(6);
PrintStackContents(s2);
Stack<string> s1 = new Stack<string>();
s1.Push("One");
s1.Push("Two");
s1.Push("Three");
PrintStackContents(s1);
}
}
Javaコード
import java.util.*;
class Test{
//Prints the contents of any generic Stack by
//specifying wildcard type
public static void PrintStackContents(Stack<?> s){
while(!s.empty()){
System.out.println(s.pop());
}
}
public static void main(String[] args){
Stack <Integer> s2 = new Stack <Integer>();
s2.push(4);
s2.push(5);
s2.push(6);
PrintStackContents(s2);
Stack<String> s1 = new Stack<String>();
s1.push("One");
s1.push("Two");
s1.push("Three");
PrintStackContents(s1);
}
}
AFAIKではC#ではそれを行うことはできません。BCLが行うことと、ジェネリックではないクラスを作成してから、前のクラスから基本動作を継承するジェネリッククラスを作成する例はたくさんあります。以下の例を参照してください。
class Foo
{
}
class Foo<T> : Foo
{
}
あなたはこのようなものを書くことができます:
Foo t = new Foo<int>();
確かにクリーンなアプローチではありませんが、使用Foo<object> x
も適している場合があります。
C#に同等のものがないというのは(まったく)真実ではありません。型として使用したり、メソッドを呼び出したりできる静的な同等物はありません。そのためには、ホルヘの答えを使用してください。
一方、リフレクションについては同等のアイデアが必要な場合があり、そこには同等のものがあります。あなたが持っている場合:
interface IFoo<T>
{
T Bar(T t, int n);
}
を使用しType
てを表すを取得できます。あまり知られておらず、あなたの質問に対する部分的な答えは、を使用して表すを取得することもできるということです。IFoo<int>
typeof(IFoo<int>)
Type
IFoo<T>
typeof(IFoo<>)
IFoo<T>
これは、リフレクションを介して使用したいが、実行時までT
わからない場合に便利です。T
Type theInterface = typeof(IFoo<>);
Type theSpecificInterface = theInterface.MakeGenericType(typeof(string));
// theSpecificInterface now holds IFoo<string> even though we may not have known we wanted to use string until runtime
// proceed with reflection as normal, make late bound calls / constructions, emit DynamicMethod code, etc.
C#には同等の構文はありません。
いいえ、C#には実際には同じ概念はありません。Fooの基本クラス(おそらく非ジェネリックFoo)を参照するか、作業しているメソッド自体をジェネリックにする必要があります(Fooを参照して、メソッドの呼び出し元にTを決定させることができます)。は)。
お役に立てば幸いです。