2013-01-15 12 views
5

in C++, è possibile scrivere codice come questo:Perchè non si richiede l'overloading degli operatori in farmaci generici

template<class T> 
T Add(T lhs, T rhs) 
{ 
    return lhs + rhs; 
} 

Ma, non si può fare qualcosa di simile in C#:

public static T Add<T>(T x, T y) where T : operator+ 
{ 
    return x + y; 
} 

C'è qualche motivo per cui? So che potrebbe essere realizzato attraverso la riflessione (generico Add con oggetti e quindi eseguire il controllo di tipo su tutto), ma questo è inefficiente e non scala bene. Quindi, di nuovo, perché?

+0

Questo è un duplicato di http://stackoverflow.com/questions/756954/arithmetic-operator-overloading-for-a-generic-class-in-c-sharp – neontapir

+0

@neontapir La risposta accettata utilizza la riflessione. Ho detto che so che si può fare in questo modo e preferirei non farlo. –

+0

Penso che nel secondo paragrafo intendi che NON puoi farlo in C#, cioè la domanda è "perché non c'è un vincolo di tipo di sovraccarico dell'operatore?" (la risposta a cui non so, btw). –

risposta

5

Non esiste una ragione intrinseca che non possa esistere. Il modo in cui i vincoli di tipo generico vengono implementati è attraverso le chiamate di interfaccia. Se esistesse un'interfaccia che fornisse un operator+, ciò avrebbe funzionato.

Questa interfaccia sarebbe richiesta per tutti i tipi rilevanti, per essere generale come l'analogo basato su modello C++.

Un altro problema sarebbe che .NET non ha più dispatch. La chiamata all'interfaccia sarebbe asimmetrica: a.Plus(b) potrebbe significare qualcosa di diverso da b.Plus(a). Equals ha lo stesso problema, btw.

Quindi questo problema probabilmente non ha soddisfatto la barra "utilità" o la barra "costo/utilità". Questo non è un problema di impossibilità, ma di problemi pratici.

Prova che è possibile: ((dynamic)a) + ((dynamic)b).

+3

Una cosa che non hai menzionato (almeno non esplicitamente): non ci * può * essere un'interfaccia che fornisce 'operator +', perché gli operatori devono essere metodi 'static' e' static' non possono essere membri di un'interfaccia – svick

+1

@svick Sto parlando di un'ipotetica versione futura di .NET. Gli operatori possono essere potenziati con versioni del metodo di istanza. In questo momento, hai ragione. – usr

3

Il CLR non supporta nativamente tali vincoli e il team di progettazione C# ha evidentemente deciso di supportare lo stesso insieme di restrizioni del CLR. Presumibilmente sia il team CLR che il team C# ritenevano che i vantaggi derivanti dall'implementazione di tale funzione non superassero i costi di speculazione, implementazione e testing.

Se si desidera utilizzare un linguaggio .NET che supporti tali vincoli, prendere in considerazione F #.

+0

Anche se credo che F # supporti tali vincoli solo in alcuni casi (a causa delle limitazioni dei vincoli CLR). – svick

+1

@svick - F # utilizza i vincoli CLR laddove possibile, ma ha il proprio formato di metadati per rappresentare molte informazioni specifiche di F # che non possono essere espresse nel sistema di tipo CLR.Uno di questi elementi è un vincolo membro, che richiede che un tipo abbia un metodo con un nome e una firma particolari. – kvb

0

Esistono diversi modi per implementare i vincoli dell'operatore e tutti sono non banali (e richiederebbero probabilmente una modifica del CLR) o hanno svantaggi significativi (ad esempio, sarebbero lenti, molto più lenti dell'aggiunta di due interi).

E questo è qualcosa che è relativamente facile da aggirare (il modo lento, generale e pericoloso di usare dynamic, o il modo veloce, specifico e sicuro di avere sovraccarichi di bajillion). Per questo motivo, tale funzione è probabilmente considerata "bella da avere" ma non sufficientemente importante da giustificare tali cambiamenti.

Problemi correlati