2010-06-15 3 views
15

Sembra che C# non supporti modelli simili a C++. Ad esempioFunzione modello in C# - Tipo di reso?

template <class myType> 
myType GetMax (myType a, myType b) { 
return (a>b?a:b); 
} 

Desidero che la mia funzione abbia un tipo di reso basato sui suoi parametri, come posso ottenerlo in C#? Come utilizzare i modelli in C#

MODIFICA: Posso utilizzare object e getType per lo stesso scopo?

+0

Io non vedo come usereste GetType per ottenere la stessa cosa, no. E non vuoi un oggetto di restituzione API a meno che tu non sia felice che il chiamante debba lanciare tutto il luogo. –

risposta

31

Il più vicino ai modelli C++ in C# è farmaci generici - ma non sono molto vicino. In particolare, non è possibile utilizzare operatori come > tra valori di tipo generico, poiché il compilatore non ne conosce (e non è possibile vincolare i tipi in base agli operatori). D'altra parte, si può scrivere:

public T GetMax<T>(T lhs, T rhs) 
{ 
    return Comparer<T>.Default.Compare(lhs, rhs) > 0 ? lhs : rhs; 
} 

o

public T GetMax<T>(T lhs, T rhs) where T : IComparable<T> 
{ 
    return lhs.CompareTo(rhs) > 0 ? lhs : rhs; 
} 

Nota che il primo di questi è nulla di sicurezza; il secondo no.

Una descrizione completa di generici va ben oltre lo scopo di una risposta Stack Overflow; MSDN ha alcune informazioni o consulta il tuo libro C# preferito.

+1

Ho ascoltato C# in profondità con alcune buone spiegazioni dei generici :) – SWeko

+1

La funzione che ho dato era solo un esempio, per quanto riguarda le funzioni diverse dal confronto? – SMUsamaShah

+0

@ Life2HO: Bene, che funzione vuoi? È un metodo di istanza specificato in un'interfaccia? Se è così, stai bene. –

0

Generics!

class MyClass<T> where T : IEnumerable (any parent class here!) 
{ 
    T myGeneric {get; set;} 
} 
1

Ti consigliamo di dare un'occhiata a generics. Sintassi:

public T GetMax<T>(T a, T b) { 
    return (a>b?a:b); 
} 

AGGIORNAMENTO a causa di alcuni commenti ... volevo solo fornire una molto veloce panoramica . Sì, immagino che non venga compilato o eseguito correttamente. Ma questa è l'idea di base su come sarebbe. Troverai risposte più complete su questo argomento - nel frattempo.

Esecuzione Sintassi:

int a = 5; 
int b = 10; 
int result = GetMax(a, b); 

Spero che questo aiuti,

saluti, Thomas

+0

Stavo per dire lo stesso ma che non verrà compilato a causa della riga 'return (a> b? A: b);' Avrà bisogno di un vincolo di interfaccia o qualcosa del genere ... –

+1

Non è possibile confrontare a e b in questo modo, poiché il compilatore non ha idea di cosa sia T. Cosa succede se il tipo T non supporta il confronto? –

2

Il tuo codice sarebbe diventato qualcosa di simile:

public T GetMax<T>(T a, T b) where T : IComparable<T> 
{ 
    return a.CompareTo(b) > 0 ? a : b; 
} 
6

Generics in C#, non sono potenti come i modelli in C++. Quello che vuoi fare non funziona in C#.

Un hack/soluzione per la vostra situazione è

public T GetMax<T>(T a, T b) where T: IComparable { 
    if(a.CompareTo(b) > 0) { 
     return a; 
    } 
    return b; 
} 
+0

La funzione che ho dato era solo un esempio, per quanto riguarda le funzioni diverse dal confronto? – SMUsamaShah

+1

@ LifeH2O: dipende - è specificato in un'interfaccia? In tal caso, puoi vincolare il tipo generico per implementare l'interfaccia (o derivare da una determinata classe base, ecc.). –

+1

Come sviluppatore C++ potresti sentirti deluso dai generici di C#. Ma sono ancora utili in molti scenari e vale la pena imparare. –

0

Vuoi dire qualche cosa come questa

public static IEnumerable<TResult> SelectIfNotNull<TSource, TResult>(this IEnumerable<TSource> source, Func<TSource, TResult> selector) 
    { 
     if (source == null) return null; 
     return source.Select(selector); 
    }