2011-08-17 5 views
5

Desidero estendere la struttura integrata di .NET per aggiungere nuovi operatori come + o -.
Userò come loro:Estendere una struttura esistente in C# per aggiungere operatori

Color c1 = Color.FromName("Red"); 
Color c2 = Color.FromName("Blue"); 
Color result = c2 - c1; 

E 'possibile? se sì, come?

+1

Non sono sicuro se questo può essere fatto ma sono molto curioso di sapere quale sarebbe il risultato del "rosso-blu"? – n8wrl

+1

@ n8wrl: Stranamente, ma mi aspetterei che ''' rimuova i valori RGB che il colore ha dall'altro. – Yuck

+2

@ n8wrl, a prescindere dal colore viola, presumibilmente :-) –

risposta

4

Non c'è modo di farlo con gli operatori integrati.

si potrebbe scrivere un metodo di estensione per tipo di esso falso però:

public static class Extensions 
{ 
    public static Color Substract(this Color color, Color theOtherColor) 
    { 
     //perform magic here! 
     //be sure to return something or this won't compile 
    } 
} 

Color c1 = Color.FromName("Red"); 
Color c2 = Color.FromName("Blue"); 
Color result = c2.Subtract(c1); 
+0

La sintassi è errata per la definizione di un metodo di estensione su 'Colore'. Deve essere una classe 'static' con metodi' static'. – Yuck

+0

Ho notato che mi mancavano i modificatori 'static'. – asawyer

+1

@asawyer, rimuovere 'return null'. 'Colore' è un valore-tipo. –

1
+0

conosco i metodi di estensione, ma mi chiedo solo la possibilità di utilizzare gli operatori. –

+0

Rispetto alla risposta di @ e & gt; –

2

Le strutture e le classi in C# condividono molte somiglianze, tuttavia una delle diverse differenze è che non è possibile creare una sottoclasse di una struttura. È possibile utilizzare un metodo di estensione per implementare un metodo Add() o Subtract(), ma non è possibile scrivere un overload di operatore in un metodo di estensione.

Se fossi in te e volessi davvero estendere la funzionalità di una struttura esistente come questa, vorrei avvolgere la struttura nella mia classe.

+0

+1 Sembra strano utilizzare i metodi di estensione. – Yuck

3

Come altri hanno suggerito, si può andare sia il modo in cui i metodi di estensione o il modo modello Decorator.

Tuttavia, considera che Color ha un discreto numero di proprietà e metodi, quindi ridirigli tutti dalla classe decoratore alla struttura Color avvolta significherà scrivere un numero elevato di piastre. Se seguire questa strada, tuttavia, è possibile infatti definire gli operatori e le conversioni anche implicite dalla classe al colore e viceversa (in modo da poterli utilizzare più intercambiabile), in questo modo:

public class MyColor { 
    public System.Drawing.Color val; 

    public MyColor(System.Drawing.Color color) 
    { 
     this.val = color; 
    } 

    public static MyColor AliceBlue 
    { 
     get { 
      return new MyColor(System.Drawing.Color.AliceBlue); 
     } 
    } 

    public override string ToString() 
    { 
     return val.ToString(); 
    } 
    // .... and so on.... 

    // User-defined conversion from MyColor to Color 
    public static implicit operator System.Drawing.Color(MyColor c) 
    { 
     return c.val; 
    } 
    // User-defined conversion from Color to MyColor 
    public static implicit operator MyColor(System.Drawing.Color c) 
    { 
     return new MyColor(c); 
    } 
} 

per testare :

+0

questo è davvero un buon esempio di riferimento, ma (nella mia situazione attuale) renderebbe tutto più difficile. bel codice, tuttavia, gli operatori impliciti puliscono le cose durante la scrittura del codice. –

+1

@can poyrazoğlu Sono d'accordo. Personalmente userò le estensioni nel tuo scenario: il mio esempio era più inteso a mostrarti quale pasticcio l'altro modo sarebbe diventato con una "grande" struttura come Color .... –

0

Se non è possibile estendere qualcosa, è anche possibile creare una classe wrapper o una struttura. In molti casi una composizione è in realtà più potente e flessibile di un'estensione.

Esso permette l'ereditarietà multipla, è possibile aggiornare facilmente/avvolgere un oggetto esistente ecc

Non sto dicendo che è la migliore risposta a questa domanda, ma sicuramente qualcosa da prendere in considerazione. :)