2011-02-08 15 views
15

Sto lavorando con un plattform .NET specifico per l'attività, che è precompilato e non OpenSource. Per alcune attività ho bisogno di estendere questa classe, ma non ereditando da essa. Voglio semplicemente aggiungere un metodo.Come si scrive un metodo di estensione per un tipo generico con vincoli sui parametri del tipo?

In un primo momento voglio visualizzare la dummycode classe esistente:

public class Matrix<T> where T : new() { 
    ... 
    public T values[,]; 
    ... 
} 

desidero far giungere a questa classe nel seguente modo:

public static class MatrixExtension { 
    public static T getCalcResult<T>(this Matrix<T> mat) { 
     T result = 0; 
     ... 
     return result; 
    } 
} 

Ho questa sintassi da molte google collegamenti quindi non ho idea se sia corretto. Il compilatore non mi dice alcun errore, ma alla fine non funziona. Alla fine voglio chiamare questa funzione nel modo seguente:

Matrix<int> m = new Matrix<int>(); 
... 
int aNumber = m.getCalcResult(); 

Quindi qualcuno ha avuto un'idea? Grazie per l'aiuto!

saluti Nem

+0

Perché pensi che non funziona? Fa un'eccezione? –

+1

Questo è il modo corretto di usare un metodo di estensione, ma invece di 'T result = 0' dovresti avere' T result = default (T) 'perché T non è inizialmente vincolato a' int'.Oltre a questo, dovresti verificare di avere l'istruzione using per includere la tua classe MatrixExtension. Puoi sempre controllare chiamando 'MatrixExtension.getCalcResult (m)' direttamente per vedere se funziona. –

+0

Almeno l'IDE mi obbliga a chiamare il metodo in questo modo: m.getCalcResult (); Ma quando provo a compilare questo ottengo un altro errore: > 'Matrix ' non contiene una definizione per 'GetValue' e nessun metodo di estensione 'GetValue' accettare un primo argomento di tipo 'Matrix ' potrebbe essere trovato (ti manca una direttiva using o un riferimento all'assembly?) In ogni modo questo modo di chiamare il metodo non ha senso perché il parametro generico T è già assegnato. –

risposta

23

è necessario aggiungere gli stessi vincoli dei parametri tipo sul metodo di estensione.

Questo è il mio tentativo di ricostruzione più vicino del vostro esempio che viene compilato ed eseguito, senza alcun errore:

public class Matrix<T> where T : new() { 
    public T[,] values; 
} 


public static class MatrixExtension { 
    public static T getCalcResult<T>(this Matrix<T> mat) where T : new() { 
     T result = new T(); 
     return result; 
    } 
} 

class Program { 
    static void Main(string[] args) { 
     Matrix<int> m = new Matrix<int>(); 
     int aNumber = m.getCalcResult(); 
     Console.WriteLine(aNumber); //outputs "0" 
} 
+0

Stavo pensando di pubblicare il mio codice, ma è esattamente lo stesso. – Marlon

+0

Puoi copiare/incollare _my_ code in un nuovo progetto per vedere cosa succede. –

+0

Sì, funziona! Ma ora so cosa non ho guardato! 'classe Matrix dove T: new()' Non l'ho assolutamente guardato. :( –

-2

Hai guardato in "Decoratori" ...

Sample showing Decorator patterns

decoratore permette di creare una classe con le sue proprietà e metodi senza fare una derivazione diretta da un classe specifica. Quindi, puoi "applicarlo" praticamente a QUALSIASI altro oggetto. Quindi puoi applicare i tuoi metodi aggiuntivi o le proprietà con cui stai cercando di lavorare.

questo campione è stato una semplice ricerca rapida che mostra un esempio allegando se stesso a "macchine" con la costruzione di "opzioni" ...

+1

Questa non è davvero una risposta alla sua domanda. –

+0

@Jim Schubert, sì ... lo so ... mentre cercavo di cercare alcuni campioni, il touch pad del mouse doveva essere stato colpito ... finché non sono tornato per regolare ... – DRapp

+0

Non l'ho fatto Votazione, ma volevo dire ... quei touchpad che invia mi prendono ogni volta. Inoltre, +1 perché un decoratore può risolvere il problema ed è una risposta valida. Il mio primo commento è stato davvero rivolto a come una domanda a frase singola è più adatta per un commento di una risposta: \ –

2

In questo momento, l'unico "errore" che vorrei vedere è questo:

T result = 0; 

si potrebbe cambiare la situazione a:

T result = default(T); 

Nel caso di tipi di valore, questo sarà pari a zero, quindi sarebbe al sicuro.

Tuttavia, si sta andando a scoprire che questo è difficile quando si arriva alla sezione "..." che hai elencato. I tipi di base (int, double, ecc.) Non implementano un metodo che è possibile utilizzare per calcolare i calcoli matematici. Questo è un long time, very highly voted request on Connect, btw.

Mentre ci sono soluzioni alternative, che rendono la vita molto difficile. A differenza dei modelli in C++, i generici di C# in realtà non supportano operazioni matematiche di tipo sicuro su tipi arbitrari.

+0

Penso che questo sia il mio problema che rimarrà. Ma quella non era la mia domanda. La mia domanda è come estendere questa classe generica. Per una classe non generica non è un problema. –

+0

@nemcija: Sì, ma estendere la classe generica è esattamente come hai fatto tu - questo non è un problema. Questo è ciò che incontrerai quando avrai risolto l'errore del compilatore. –

Problemi correlati