Non C # hanno un equivalente di battitura strutturale della Scala?
-
26-09-2019 - |
Domanda
In Scala, posso definire tipologie strutturali come segue:
type Pressable = { def press(): Unit }
Questo significa che posso definire una funzione o un metodo che prende come un qualcosa di argomento che è Pressable, in questo modo:
def foo(i: Pressable) { // etc.
L'oggetto che mi passa per questa funzione deve essere definita per un metodo chiamato stampa () che corrisponde alla firma tipo definito nel tipo - non prende argomenti, restituisce Unit (la versione di Scala di vuoto)
.I può anche utilizzare il tipo di linea strutturale:
def foo(i: { def press(): Unit }) { // etc.
Si permette in sostanza al programmatore di avere tutti i vantaggi di battitura anatra, pur avendo il vantaggio di controllo di tipo in fase di compilazione.
La C # hanno qualcosa di simile? Ho Googled, ma non riesco a trovare nulla, ma io non sono a conoscenza di C # in modo approfondito. Se non ci sono, ci sono piani per aggiungere questo?
Soluzione
Non ci sono, e non prevede che io sappia. Solo nome (anziché strutturali) sottotipizzazione (ad esempio interfacce).
(Altri potrebbero voler vedere anche
http://en.wikipedia.org/wiki/Nominative_type_system
http://en.wikipedia.org/wiki/Structural_type_system
)
(Alcune persone possono far valere alcuni casi angolo esotiche, come l'affermazione foreach
utilizzando tipizzazione strutturale per GetEnumerator
, ma questo è il noreferrer eccezione piuttosto che la regola.)
Altri suggerimenti
Non c'è un modo per definire i tipi strutturali che ha una funzione particolare. V'è una libreria che aggiunge il supporto a digitare anatra in C # che può essere trovato qui .
Questo è l'esempio di progetto di Typing Duck. Si prega di notare che il tipizzazione anatra accade in fase di esecuzione e può non . È la mia comprensione, inoltre, che questa libreria genera i proxy per i tipi che vengono digitati anatra, che è lontano grida dalla elegante supporto in fase di compilazione che si gode in Scala. Questo è più probabile che, come buono come si arriva con questa generazione di C #.
public interface ICanAdd
{
int Add(int x, int y);
}
// Note that MyAdder does NOT implement ICanAdd,
// but it does define an Add method like the one in ICanAdd:
public class MyAdder
{
public int Add(int x, int y)
{
return x + y;
}
}
public class Program
{
void Main()
{
MyAdder myAdder = new MyAdder();
// Even though ICanAdd is not implemented by MyAdder,
// we can duck cast it because it implements all the members:
ICanAdd adder = DuckTyping.Cast<ICanAdd>(myAdder);
// Now we can call adder as you would any ICanAdd object.
// Transparently, this call is being forwarded to myAdder.
int sum = adder.Add(2, 2);
}
}
Questo è il C # modo per raggiungere la stessa cosa usando il buon vecchio noioso interfacce.
interface IPressable {
void Press();
}
class Foo {
void Bar(IPressable pressable) {
pressable.Press();
}
}
class Thingy : IPressable, IPushable, etc {
public void Press() {
}
}
static class Program {
public static void Main() {
pressable = new Thingy();
new Foo().Bar(pressable);
}
}
Come altri hanno notato, questo non è davvero disponibili in .NET (come questo è più una questione di runtime di una lingua). Tuttavia, .NET 4.0 supporta cosa simile per le interfacce COM importati e credo che questo potrebbe essere utilizzato per implementare la tipizzazione strutturale per .NET. Vedi questo post del blog:
Non ho provato a giocare con questo me stesso ancora, ma penso che potrebbe permettere agli autori del compilatore di scrivere lingue con tipizzazione strutturale per .NET. (L'idea è che voi (o un compilatore) definirebbe un'interfaccia dietro la scena, ma che avrebbe funzionato, perché le interfacce sarebbero trattati come equivalenti grazie alla funzione di COM di equivalenza).
Inoltre, C # 4.0 supporta la parola chiave dynamic
che, credo, potrebbe essere interpretato come una digitazione strutturale (con nessun controllo di tipo statico). La parola chiave consente di chiamare i metodi su qualsiasi oggetto senza knowning (a tempo di compilazione) se l'oggetto avrà i metodi richiesti. Questo è essenzialmente la stessa cosa come il progetto "duck typing" di cui parla Igor (ma questo è, naturalmente, non una vera e propria battitura strutturale).
Il pattern awaitable in C # può forse essere interpretata come limitata, un'istanza ad hoc di sottotipaggio strutturale / tipizzazione esistenziale. Il compilatore solo await
oggetti che hanno accesso ad un metodo GetAwaiter()
che restituisce un oggetto INotifyCompletion
con uno specifico set di metodi e proprietà. Poiché né l'oggetto 'awaitable', né le esigenze oggetto 'awaiter' per implementare qualsiasi interfaccia (tranne INotifyCompletion
nel caso di quest'ultimo), await
è simile a un metodo che accetta strutturalmente digitato oggetti awaitable.