C# 中是否有“匿名”通用标签,例如“?” 在爪哇?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/116830/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-03 14:28:07  来源:igfitidea点击:

Is there an "anonymous" generic tag in C#, like '?' in Java?

提问by EfForEffort

In Java, one can declare a variable parameterised by an "unknown" generic type, which looks like this:

在 Java 中,可以声明一个由“未知”泛型类型参数化的变量,如下所示:

Foo<?> x;

Is there an equivalent construct to this question-mark, in C#?

在 C# 中,是否有与此问号等效的构造?

采纳答案by Sergio Acosta

The short answer is no. There isn't an equivalent feature in C#.

最简洁的答案是不。C# 中没有等效的功能。

A workaround, from C# from a Java developer's perspectiveby Dare Obasanjo:

Dare Obasanjo从 Java 开发人员的角度C#提出的解决方法:

In certain cases, one may need create a method that can operate on data structures containing any type as opposed to those that contain a specific type (e.g. a method to print all the objects in a data structure) while still taking advantage of the benefits of strong typing in generics. The mechanism for specifying this in C# is via a feature called generic type inferencing while in Java this is done using wildcard types. The following code samples show how both approaches lead to the same result.

在某些情况下,人们可能需要创建一种方法来操作包含任何类型的数据结构,而不是包含特定类型的数据结构(例如打印数据结构中所有对象的方法),同时仍然利用泛型中的强类型。在 C# 中指定这一点的机制是通过称为泛型类型推断的功能,而在 Java 中这是使用通配符类型完成的。以下代码示例显示了两种方法如何导致相同的结果。

C# Code

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 Code

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); 
    }
}

回答by bdukes

No, there isn't really the same concept in C#. You would need to refer to a base class of Foo (maybe a non-generic Foo), or make the method you're working in generic itself (so that you can refer to Foo, and let the caller of your method determine what T is).

不,C# 中没有真正相同的概念。您需要引用 Foo 的基类(可能是非泛型 Foo),或者使您正在使用的方法本身具有泛型(以便您可以引用 Foo,并让您的方法的调用者确定 T是)。

Hope that helps.

希望有帮助。

回答by Compile This

There isn't an equivalent syntax in C#.

C# 中没有等效的语法。

回答by Jorge Ferreira

AFAIK you can not do that in C#. What the BCL does and there are plenties of examples there is to create a class that is not generic and then create a generic class that inherits the base behavior from the previous one. See example below.

AFAIK 你不能在 C# 中做到这一点。BCL 所做的以及有大量示例是创建一个非泛型的类,然后创建一个继承前一个基本行为的泛型类。请参阅下面的示例。

class Foo
{
}

class Foo<T> : Foo
{
}

The you can write something like this:

你可以这样写:

Foo t = new Foo<int>();

回答by Doug McClean

It isn't (quite) true that there is no equivalent in C#. There is no static equivalent that you can use as a type, or call methods on, true enough. For that, use Jorge's answer.

在 C# 中没有等价物并不是(完全)正确的。没有可以用作类型或调用方法的静态等效项,这是真的。为此,请使用Jorge 的答案

On the other hand, sometimes you need the equivalent idea for reflection, and there is an equivalent there. If you have:

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

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

you can get a Typethat represents IFoo<int>using typeof(IFoo<int>). Less well known, and a partial answer to your question, is that you can also get a Typethat represents IFoo<T>using typeof(IFoo<>).

你可以得到一个Type代表IFoo<int>使用typeof(IFoo<int>). 不太为人所知,并且对您的问题的部分答案是,您还可以获得Type代表IFoo<T>使用typeof(IFoo<>).

This is useful when you want to use IFoo<T>for some Tthrough reflection and won't know Tuntil runtime.

当您想通过反射使用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.

回答by Dani

While admittedly being not the clean approach, using Foo<object> xmay also be suitable.

虽然不可否认不是干净的方法,但使用Foo<object> x也可能是合适的。