Pregunta

En Java, se puede declarar una variable parametrizada por un tipo genérico "desconocido", que tiene este aspecto:

Foo<?> x;

¿Existe una construcción equivalente a este signo de interrogación en C#?

¿Fue útil?

Solución

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

Una solución alternativa, desde C# desde la perspectiva de un desarrollador de Java por Dare Obasanjo:

En ciertos casos, es posible que sea necesario crear un método que pueda operar en estructuras de datos que contengan cualquier tipo en lugar de aquellas que contienen un tipo específico (por ejemplo,un método para imprimir todos los objetos en una estructura de datos) y al mismo tiempo aprovechar los beneficios de la tipificación segura en genéricos.El mecanismo para especificar esto en C# es a través de una característica llamada inferencia de tipos genéricos, mientras que en Java esto se hace usando tipos comodín.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 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); 
    }
}

Otros consejos

AFAIK no puedes hacer eso en C#.Lo que hace el BCL y hay muchos ejemplos es crear una clase que no es genérica y luego crear una clase genérica que hereda el comportamiento base de la anterior.Vea el ejemplo a continuación.

class Foo
{
}

class Foo<T> : Foo
{
}

Puedes escribir algo como esto:

Foo t = new Foo<int>();

Si bien es cierto que no es un enfoque limpio, utilizar Foo<object> x también puede ser adecuado.

No existe una sintaxis equivalente en C#.

No es (del todo) cierto que no exista un equivalente en C#.No existe un equivalente estático que pueda usar como tipo o llamar a métodos, es cierto.Para eso, use la respuesta de jorge.

Por otro lado, a veces se necesita la idea equivalente para reflexionar, y ahí hay un equivalente.Si usted tiene:

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

puedes conseguir un 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 quieres usar IFoo<T> para algunos T a través de la reflexión y no lo 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.

No, en realidad no existe el mismo concepto en C#.Necesitaría hacer referencia a una clase base de Foo (tal vez un Foo no genérico), o hacer que el método en el que está trabajando sea genérico (para que pueda consultar Foo y dejar que la persona que llama a su método determine qué T es).

Espero que ayude.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top