有没有“匿名” C#中的通用标签,如'?'在Java?
题
在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&lt; object&gt; x
也可能适用。
C#中没有等效的语法。
C#中没有相应的东西,这是不完全正确的。没有静态等价物可以用作类型,或者调用方法,就足够了。为此,请使用 Jorge的回答一>
另一方面,有时你需要相同的反思思想,并且有一个等价物。如果你有:
interface IFoo<T>
{
T Bar(T t, int n);
}
您可以使用 typeof(IFoo&lt; int&gt;)
获取代表 IFoo&lt; int&gt;
的 Type
。鲜为人知,并且对您的问题的部分答案是,您还可以使用 typeof(IFoo&lt;&gt;)获得代表
IFoo&lt; T&gt;
的 Type
。 )代码>
当您想通过反射使用 IFoo&lt; T&gt;
来执行某些 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#中的概念并不相同。您需要引用Foo的基类(可能是非泛型Foo),或者使用通用本身的方法(这样您可以引用Foo,并让您的方法的调用者确定什么T是)。
希望有所帮助。