Domanda

In Java, si può dichiarare una variabile parametrizzata da un "sconosciuto" tipo generico, che assomiglia a questo:

Foo<?> x;

Esiste un costrutto equivalente a questo punto interrogativo, in C #?

È stato utile?

Soluzione

La risposta breve è no. Non esiste una funzione equivalente in C #.

Una soluzione alternativa, da C # dal punto di vista di uno sviluppatore Java di Dare Obasanjo:

In alcuni casi, potrebbe essere necessario creare un metodo in grado di operare su strutture di dati contenenti qualsiasi tipo rispetto a quelli che contengono un tipo specifico (ad esempio un metodo per stampare tutti gli oggetti in una struttura di dati) sfruttando comunque i vantaggi della tipizzazione forte in generici. Il meccanismo per specificare questo in C # è tramite una funzione chiamata inferenza di tipo generico mentre in Java questo viene fatto usando tipi di caratteri jolly. I seguenti esempi di codice mostrano come entrambi gli approcci portano allo stesso risultato.

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

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

Altri suggerimenti

AFAIK non puoi farlo in C #. Quello che fa il BCL e ci sono molti esempi che esiste per creare una classe che non è generica e quindi creare una classe generica che eredita il comportamento di base da quello precedente. Vedi esempio di seguito.

class Foo
{
}

class Foo<T> : Foo
{
}

Puoi scrivere qualcosa del genere:

Foo t = new Foo<int>();

Pur non essendo l'approccio pulito, usando Foo < object > x può anche essere adatto.

Non esiste una sintassi equivalente in C #.

Non è (abbastanza) vero che non esiste un equivalente in C #. Non esiste un equivalente statico che puoi utilizzare come tipo o chiamare metodi su, abbastanza vero. Per questo, usa Risposta di Jorge .

D'altra parte, a volte hai bisogno dell'idea equivalente di riflessione, e lì c'è un equivalente. Se hai:

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

puoi ottenere un Type che rappresenta IFoo < int > usando typeof (IFoo < int >) . Meno noto, e una risposta parziale alla tua domanda, è che puoi anche ottenere un Tipo che rappresenta IFoo < T > usando typeof (IFoo < > ) .

Questo è utile quando si desidera utilizzare IFoo < T > per alcuni T attraverso la riflessione e non si conosce T fino al runtime.

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, non c'è davvero lo stesso concetto in C #. Dovresti fare riferimento a una classe base di Foo (forse un Foo non generico), o rendere il metodo che stai lavorando in modo generico stesso (in modo da poter fare riferimento a Foo e lasciare che il chiamante del tuo metodo determini quale T è).

Spero che sia d'aiuto.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top