Question

Scala, je peux définir des types de structure suivante comme suit:

type Pressable = { def press(): Unit }

Cela signifie que je peux définir une fonction ou une méthode qui prend comme quelque chose argument qui est Pressable, comme ceci:

def foo(i: Pressable) { // etc.

L'objet que je passe à cette fonction doit avoir défini pour une méthode rapide appelée () qui correspond à la signature de type défini dans le type - prend aucun argument, renvoie l'unité (la version de Scala de vide)

.

Je peux même utiliser la ligne de type structural:

def foo(i: { def press(): Unit }) { // etc.

Il permet essentiellement le programmeur d'avoir tous les avantages de frappe de canard tout en ayant l'avantage de la vérification du type de compilation.

Est-ce que C # a quelque chose de similaire? J'ai googlé mais ne trouve rien, mais je ne suis pas familier avec C # en profondeur. S'il n'y a pas, est-il prévu d'ajouter cela?

Était-ce utile?

La solution

Non, et pas de plans que je connais. Seulement nommé (plutôt que de structure) de sous-typage (par exemple des interfaces).

(D'autres peuvent vouloir voir aussi

http://en.wikipedia.org/wiki/Nominative_type_system

http://en.wikipedia.org/wiki/Structural_type_system

)

(Quelques personnes peuvent signaler quelques cas d'angle exotiques, comme la déclaration de foreach en utilisant le typage structurel pour GetEnumerator, mais c'est la noreferrer exception plutôt que la règle.)

Autres conseils

Il n'y a pas un moyen de définir les types de structure qui a une fonction particulière. Il y a une bibliothèque qui ajoute le support de frappe de canard à C # qui se trouve .

Ceci est l'exemple de Duck projet de frappe. S'il vous plaît noter que le frappe de canard arrive à l'exécution et peut échouer . Je crois comprendre aussi que cette bibliothèque génère des proxys pour les types qui sont tapés canard, qui est bien loin de l'élégant support de compilation qui est apprécié à Scala. Ceci est probablement aussi bon qu'il obtient avec cette génération de 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);
    }
}

Ceci est la voie C # de réaliser la même chose en utilisant le bon vieux interfaces ennuyeux.

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);
 }
}

Comme d'autres ont noté, ce n'est pas vraiment disponible dans .NET (comme cela est plus une question de l'exécution d'une langue). Cependant, .NET 4.0 pour supports chose similaire interfaces COM importées et je crois que cela pourrait être utilisé pour la mise en œuvre pour la saisie de structure .NET. Voir ce billet de blog:

Je n'ai pas essayé de jouer avec moi-même, mais je pense qu'il pourrait permettre aux auteurs d'écrire compilateur langues avec la saisie de structure pour .NET. (L'idée est que vous (ou un compilateur) définiriez une interface derrière la scène, mais cela fonctionnerait, parce que les interfaces seraient traitées comme équivalentes grâce à la fonction d'équivalence COM).

En outre, C # 4.0 prend en charge le mot-clé dynamic qui, je pense, pourrait être interprété comme un typage structurel (sans vérification de type statique). Le mot-clé vous permet d'appeler des méthodes sur un objet sans knowning (à la compilation) si l'objet aura les méthodes nécessaires. Ceci est essentiellement la même chose que le projet « frappe de canard » mentionné par Igor (mais qui est, bien sûr, pas un typage structurel approprié).

Le modèle awaitable en C # peut-être interprété comme une limitation, ad hoc instance de sous-typage structurel / frappe existentielle. Le compilateur ne await objets qui ont accès à une méthode de GetAwaiter() que les rendements tout objet INotifyCompletion avec un ensemble spécifique de méthodes et propriétés. Etant donné que ni l'objet « awaitable » ni l'objet « awaiter » doit mettre en œuvre une interface (sauf INotifyCompletion dans le cas de celui-ci), await est similaire à une méthode qui accepte des objets awaitable structurellement tapé.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top