39

Java では、次のような「不明な」ジェネリック型によってパラメーター化された変数を宣言できます。

Foo<?> x;

C# で、この疑問符に相当する構造はありますか?

4

6 に答える 6

38

簡単な答えはノーです。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); 
    }
}
于 2008-09-22T19:25:11.657 に答える
24

AFAIKではC#ではそれを行うことはできません。BCLが行うことと、ジェネリックではないクラスを作成してから、前のクラスから基本動作を継承するジェネリッククラスを作成する例はたくさんあります。以下の例を参照してください。

class Foo
{
}

class Foo<T> : Foo
{
}

あなたはこのようなものを書くことができます:

Foo t = new Foo<int>();
于 2008-09-22T19:16:34.970 に答える
14

確かにクリーンなアプローチではありませんが、使用Foo<object> xも適している場合があります。

于 2012-07-06T08:19:02.580 に答える
8

C#に同等のものがないというのは(まったく)真実ではありません。型として使用したり、メソッドを呼び出したりできる静的な同等物はありません。そのためには、ホルヘの答えを使用してください。

一方、リフレクションについては同等のアイデアが必要な場合があり、そこには同等のものがあります。あなたが持っている場合:

interface IFoo<T>
{
  T Bar(T t, int n);
}

を使用しTypeてを表すを取得できます。あまり知られておらず、あなたの質問に対する部分的な答えは、を使用して表すを取得することもできるということです。IFoo<int>typeof(IFoo<int>)TypeIFoo<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.
于 2008-09-22T19:34:56.597 に答える
5

C#には同等の構文はありません。

于 2008-09-22T19:15:39.637 に答える
2

いいえ、C#には実際には同じ概念はありません。Fooの基本クラス(おそらく非ジェネリックFoo)を参照するか、作業しているメソッド自体をジェネリックにする必要があります(Fooを参照して、メソッドの呼び出し元にTを決定させることができます)。は)。

お役に立てば幸いです。

于 2008-09-22T19:14:55.007 に答える