2015-04-03 9 views
23

In Java, posso avere un oggetto come questo:Posso inizializzare le proprietà pubbliche di una classe utilizzando un tipo diverso in C#?

public class MyObject { 

    private Date date; 

    public Date getDate() { 
     return date; 
    } 

    public void setDate(Date date) { 
     this.date = date; 
    } 

    public void setDate(String date) { 
     this.date = parseDateString(date); 
    } 

    private Date parseDateString(String date) { 
     // do magic here 
     return dateObj; 
    } 

} 

Questo è bello, perché ho un getter per le mie proprietà, e molteplici setter. Posso impostare la proprietà "date" passando in un oggetto Date o in una stringa e lasciando che la classe lo decida.

In C# sembra che le cose siano un po 'diverse. Posso fare questo:

public class MyObject 
{ 
    public DateTime Date { get; set; } 
} 

La stenografia qui è ovviamente ottimale. Tuttavia, non sono sicuro se ci sia un modo integrato per sovraccaricare il setter per accettare più tipi. Mi rendo conto che potrei creare un metodo pubblico separato per impostare il valore, ma ciò significherebbe sacrificare la possibilità di utilizzare gli inizializzatori di oggetti.

C'è un modo per sovraccaricare direttamente il setter su proprietà pubbliche per C#? O è solo una limitazione della lingua e non può essere fatto?

+2

Non è una risposta, ma vorrei lasciare l'analisi stringa al momento all'esterno di 'MyClass'. In C# è sufficiente usare 'DateTime.Parse', comunque. –

risposta

22

Tutte le altre risposte sono corrette ...ma se insistete, lo si può fare in diversi modi:

  1. Utilizzare una seconda proprietà con solo un setter:

    public string DateText { set { Date = ParseDateString(value); } } 
    

    evitare questo, se possibile, ma aggiunge solo confusione :-)

  2. Utilizzare metodi anziché proprietà (come in Java). I metodi possono essere sovraccaricati. Questo dovrebbe essere il modo più raccomandato.

  3. utilizzare una classe personalizzata (invece di DateTime) e fornire conversioni implicite tra DateTime, string, e la classe. Non consigliato a meno che non lo userai ovunque.

  4. Modificare la proprietà di object e fornire le conversioni nel setter: per favore non fare questo

+1

Avrei grassetto-enfatizza il ** se insisti ** parte, le proprietà di solo set sono un odore di codice nei miei libri ... + 1 per completezza però;) –

+0

@ Mat'sMug sicuramente. Ho modificato per aggiungere commenti aggiuntivi :-) – Jcl

+3

Le conversioni implicite sono molto complicate quando si tratta di leggere il codice. Invece potresti usare le conversioni esplicite. –

10

Le proprietà automatiche non supportano questo. Quindi dovrai fare lo stesso come fai in Java.

Naturalmente è possibile combinare anche questi: fornire una proprietà automatica e ulteriori metodi di impostazione per impostare la proprietà utilizzando tipi diversi.

public class MyObject 
{ 
    public DateTime Date { get; set; } 

    public void SetDate(string date) 
    { 
     this.Date = DateTime.Parse(date); 
    }  
} 
16

Bene, stai confrontando le mele con le banane. Quello che avete in Java qui:

public void setDate(Date date) { 
    this.date = date; 
} 

public void setDate(String date) { 
    this.date = parseDateString(date); 
} 

sarebbe simile a questa in C#:

public void SetDate(Date date) 
{ 
    this.date = date; 
} 

public void SetDate(String date) 
{ 
    this.date = ParseDateString(date); 
} 

L'unica differenza è il nome PascalCase membri e la posizione della coppia scope-apertura.

Il codice Java ha sovraccaricato i metodi ; il precedente C# ha metodi sovraccaricati.

per quanto ne so non si può sovraccaricare un setter di proprietà, perché:

public DateTime Date 
{ 
    get { return this.date; } 
    set { this.date = value; } 
} 

... il tipo di value è determinato dal tipo di elemento, qui DateTime.

Quindi, se volete metodo sovraccarichi, sovraccaricare metodi, non proprietà. Ricorda che le proprietà C# sono solo zucchero di sintassi per i metodi getter & setter.

+0

Non penso ci sia alcun motivo concettuale per cui .NET non abbia potuto permettere alle proprietà di avere setter sovraccarichi, se i linguaggi .NET, vedendo la sintassi delle proprietà, usassero la stessa logica di sovraccarico di un metodo (con il tipo di mano destra dell'espressione come primo argomento). Semanticamente una cosa del genere sarebbe dubbia nei casi in cui il risultato sarebbe diverso dal forzare il valore da impostare sul tipo principale della proprietà, ma nei casi in cui più tipi sono reciprocamente convertibili, l'impostazione di un puntello direttamente su un particolare tipo potrebbe essere più veloce di conversione e quindi impostazione. – supercat

+1

@supercat Penso che sia più un vincolo di linguaggio/sintassi (C#) che una cosa di .NET. VB.NET supporta getter/setter parametrizzati (diamine, VB6!). Le proprietà vengono compilate con i metodi 'get_' e' set_' in CIL se ricordo correttamente. –

+0

In VB.NET e C#, la risoluzione della proprietà si verifica prima che il sistema determini cosa viene fatto con la proprietà. In caso contrario, si potrebbe avere un'interfaccia 'IReadableFoo ' che espone una proprietà' Foo' con un getter e 'IWritableFoo ' che espone un' Foo' con un setter e quindi 'IReadWriteFoo ' eredita semplicemente entrambi . A causa del modo in cui viene eseguito il binding, tuttavia, né il getter né il setter funzioneranno su una variabile di tipo 'IReadWriteFoo '; un tentativo di dire "it.Foo = 9;' o 'x = it.Foo; 'verrà rifiutato perché è (presumibilmente) ambiguo se si sta tentando di utilizzare ... – supercat

10

ho intenzione di scrivere una risposta diversa e sostengono che

public void setDate(Date date) { 
    this.date = date; 
} 

public void setDate(String date) { 
    this.date = parseDateString(date); 
} 

è una cattiva pratica per cominciare.

Effettuando quanto sopra, si sostiene che sia le stringhe che le date sono valori validi per Date. Questo non è il caso - quello che vuoi veramente è un Date. Se l'utente ha una stringa e desidera convertirla a Date, è necessario affidarsi alla funzionalità di analisi delle stringhe nell'API Date(DateFormat.parse() in Java, DateTime.Parse() in C#), non nell'API.

Se Date è una classe definita da voi e si vuole veramente Date e string per essere intercambiabili, si dovrebbe utilizzare implicit conversations nella classe Date, non chiedendo agli utenti della vostra classe Date a scrivere sovraccarichi.

Problemi correlati