2008-09-22 26 views

Respuesta

26

La respuesta corta es no. No hay una característica equivalente en C#.

Una solución, de C# from a Java developer's perspective de Dare Obasanjo:

En ciertos casos, uno puede necesitar crear un método que puede operar sobre estructuras de datos que contengan cualquier tipo en oposición a los que contienen un tipo específico (por ejemplo, un método para imprima todos los objetos en una estructura de datos) al mismo tiempo que aprovecha los beneficios de la tipificación fuerte en genéricos. El mecanismo para especificar esto en C# es a través de una función llamada inferencia de tipo genérico, mientras que en Java esto se hace usando tipos de comodines. Los siguientes ejemplos de código muestran cómo ambos enfoques conducen al mismo resultado.

Código 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); 
    } 
} 

Código de 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); 
    } 
} 
+1

La inferencia similar a C# también funciona en Java 6. ¿Todavía hay uso de en Java? –

+21

Esto no responde la pregunta. La respuesta es no". El truco que se muestra arriba demuestra una solución para la conversión de captura de Java en C# que funciona con la conversión de invocación de método, pero no será útil en la conversión de asignación o en una expresión de conversión. – Mishax

+4

De hecho, esta es la forma más larga de decir "no" que he visto :) – David

1

No, realmente no existe el mismo concepto en C#. Tendrías que consultar una clase base de Foo (quizás un Foo no genérico), o hacer que el método en el que trabajas sea genérico en sí mismo (para que puedas referirte a Foo, y que el que llama de tu método determine qué T es).

Espero que ayude.

4

No hay una sintaxis equivalente en C#.

12

AFAIK no se puede hacer eso en C#. Lo que hace el BCL y hay una gran cantidad de ejemplos para crear una clase que no sea genérica y luego crear una clase genérica que hereda el comportamiento base del anterior. Vea el ejemplo a continuación.

class Foo 
{ 
} 

class Foo<T> : Foo 
{ 
} 

El se puede escribir algo como esto:

Foo t = new Foo<int>(); 
3

No es (bastante) cierto que no hay equivalente en C#. No existe un equivalente estático que pueda usar como tipo, o invocar métodos, lo suficientemente cierto. Para eso, use Jorge's answer.

Por otro lado, a veces necesita la idea equivalente para la reflexión, y hay un equivalente allí. Si usted tiene:

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

se puede obtener una Type que representa IFoo<int> usando typeof(IFoo<int>). Menos conocido, y una respuesta parcial a su pregunta, es que también puede obtener un Type que representa IFoo<T> usando typeof(IFoo<>).

Esto es útil cuando desea usar IFoo<T> para algunos T a través de la reflexión y no sabrá T hasta el tiempo de ejecución.

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. 
11

Si bien es cierto que no es el enfoque limpio, usando Foo<object> x también pueden ser adecuados.

+2

-1: el uso de 'object' restringe el tipo genérico a todos los tipos que tienen el' objeto 'de superclase común. –

+3

Funciona con todo: primitivos, objetos de clase, estructuras, enumeraciones ... 'List list = new List (); list.Add (1); list.Add (new DateTime()); list.Add (nuevo MyStruct()); list.Add (MyEnum.Enum1); ' – Dani

+0

Admito que tienes razón. –