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# 中没有等价物,这不是(完全)正确的。没有任何静态等价物可以用作类型或调用方法,这是真的。为此,请使用Jorge 的回答

另一方面,有时您需要等效的思想来进行反思,并且那里有等效的想法。如果你有:

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

你可以得到一个Type代表IFoo<int>using typeof(IFoo<int>)。鲜为人知,对您的问题的部分回答是,您还可以获得Type表示IFoo<T>using的 a 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 回答