2010-07-12 9 views
27

Sono interessante in alcune scelte di progettazione del linguaggio C#. C'è una regola in C# spec che permette di utilizzare i gruppi di metodo come le espressioni di is dell'operatore:Progettazione linguaggio C#: gruppo di metodi all'interno dell'operatore `is`

class Foo { 
    static void Main() { if (Main is Foo) Main(); } 
} 

condizione di cui sopra è sempre false, come la specifica dice:

7.10.10 Il è operatore

Se e è un gruppo metodo o nullo letterale, di se il tipo di e è un tipo di riferimento o un tipo nullable e il valore di e è nullo, il risultato è falso.

Le mie domande: qual è lo scopo/point/motivo di permettere di usare la lingua elemento C# senza rappresentanza runtime CLR come gruppi di metodo all'interno dell'operatore come "runtime" come is?

+2

+1 _no indizio _... – SLaks

+0

Questo è ... stupendo. La sezione sull'operatore 'as' non fa menzione dei gruppi di metodi. –

+0

@Tim: Ma l'operatore "as" è definito come zucchero sintattico per una combinazione di cast, l'operatore condizionale e l'operatore "is", quindi l'operatore "as" non deve menzionare i gruppi metodo. –

risposta

21

qual è lo scopo/punto/motivo di consentire l'uso dell'elemento di linguaggio C# senza rappresentazione di runtime in CLR come i gruppi di metodi all'interno di tale operatore "runtime" come è?

L'archivio delle note di progettazione linguistica non fa menzione del motivo per cui è stata presa questa decisione, quindi qualsiasi ipotesi di risposta sarà una congettura. Dicono che se il risultato dell '"è" può essere statisticamente determinato a essere sempre vero o falso, che sia così determinato e produca un avvertimento. Sembra plausibile che questo possa essere semplicemente un errore.

Il motivo più comune per trasformare ciò che potrebbe essere correttamente un errore in un avviso (o semplicemente consentirlo) è perché ciò riduce l'onere sui produttori di programmi che generano automaticamente codice. Tuttavia, non vedo uno scenario davvero avvincente qui.

UPDATE:

Ho appena controllato le specifiche C# 1.0. Non ha questo linguaggio in esso. Non dice nulla riguardo a null o argomenti del gruppo di metodi. Ovviamente non dice nulla sulle conversioni dei gruppi di metodi, perché in C# 1.0 non ci sono state conversioni di gruppo di metodi implicite; dovevi chiamare esplicitamente "nuova D (M)" se vuoi convertire il metodo M a delegare il tipo D.

Quest'ultimo punto è la giustificazione per "M è D" che restituisce falso anziché vero; Non si poteva legalmente dire "D d = M;" quindi perché "M is D" è vero?

Naturalmente in C# 2.0 questo ha meno senso, dal momento che è possibile dire "D d = M;" in C# 2.0.

Ho anche solo chiesto a una delle persone presenti quando l'operatore "è" è stato progettato e non ha memoria di aver mai deciso di risolvere questa domanda in un modo o nell'altro. Il suo sospetto era che il progetto originale dell'operatore "è" fosse quello di non dare alcun errore, solo avvertimenti, e che tutto il testo nelle specifiche su cosa fare con i gruppi di metodi e null e cosa non fosse stato aggiunto post-hoc, per il Versione C# 2.0 della specifica e basata su ciò che il compilatore ha effettivamente fatto.

In breve, sembra che si trattasse di un foro di progettazione in C# 1.0 che è stato coperto quando la specifica è stata aggiornata per C# 2.0. Non sembra che questo comportamento specifico sia stato desiderato e implementato deliberatamente.

Questa teoria è rafforzata dal fatto che i metodi anonimi do producono un errore quando vengono utilizzati come argomento per "è" in C# 2.0. Non sarebbe un cambiamento irrisolto farlo, ma è essere una modifica di rottura per rendere "M è D" improvvisamente iniziare restituendo true o essere un errore.

ULTERIORI UPDATE:

Mentre indaga questo ho imparato qualcosa di interessante. (Per me.) Quando la funzionalità è stata originariamente progettata, il progetto doveva consentire il nome di un tipo, o un oggetto Tipo come argomento della mano destra su "è". Quell'idea fu abbandonata ben prima che il C# 1.0 venisse spedito.

3

innanzitutto un metodo non è un tipo, MSDN indica chiaramente le seguenti:

L'operatore is is utilizzato per controllare se il tipo di runtime di un oggetto è compatibile con un dato tipo

Esempio

public static void Test (object o) 
{ 
    Class1 a; 

    if (o is Class1) {} 
} 

From MSDN:

An è espressione risulta vera se entrambe le seguenti condizioni vengono soddisfatte:

  • espressione non è nullo.
  • espressione può essere espressi per digitare. Cioè, un'espressione cast della forma (tipo) (espressione) verrà completata senza generare un'eccezione. Per ulteriori informazioni, vedere 7.6.6 Espressioni di trasmissione.

Quindi il motivo per cui il tuo esempio è false terre sul secondo punto, deve essere calcinabile per un tipo specifico.

Spero di non aver dimenticato la domanda.

+1

La domanda è, perché "Main is Class1" non è un errore del compilatore? – SLaks

+0

@SLacks: Forse dovremmo usare Reflector per indagare ulteriormente su questo. – Andreas

+0

@SLaks, usando ReShaper ricevo un avviso con questo messaggio: "L'espressione data non viene mai fornita di un tipo". Controllo con Reflector ora .. –