Pregunta

En Scala, I puede definir tipos estructurales como sigue:

type Pressable = { def press(): Unit }

Esto significa que puedo definir una función o un método que toma como argumento algo que es inyectada, como esto:

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

El objeto que me pase a esta función debe haber definido para ello un método llamado de prensa () que coincide con la firma tipo definido en el tipo - no tiene argumentos, devuelve Unidad (versión de Scala de vacío)

.

Incluso puede utilizar el tipo de línea estructural:

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

Básicamente permite que el programador tiene todas las ventajas de la tipificación de pato sin dejar de tener el beneficio de la comprobación de tipos en tiempo de compilación.

¿El C # tiene algo similar? He buscado en Google, pero no puedo encontrar nada, pero no estoy familiarizado con C # en profundidad. Si no los hay, ¿hay planes de añadir esto?

¿Fue útil?

Solución

No hay, ni planes, que yo sepa. Sólo llamado (en lugar de estructural) subtipificación (por ejemplo, interfaces).

(Otros pueden querer ver también

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

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

)

(algunas personas pueden señalar algunos casos de esquina exóticos, como la declaración foreach utilizando la tipificación estructural para GetEnumerator, pero esta es la noreferrer excepción y no la regla.)

Otros consejos

No hay una manera de definir los tipos estructurales que tiene una función particular. Hay una biblioteca que añade soporte tipificación de pato a C # que se puede encontrar aquí .

Este es el ejemplo de proyecto Typing pato. Tenga en cuenta la duck typing sucede en tiempo de ejecución y puede fallar . Tengo entendido también que esta biblioteca genera proxies para los tipos que se escriben de pato, que se Far Cry de la elegante soporte en tiempo de compilación que se disfruta en Scala. Esto es muy probablemente tan bueno como se pone con esta generación 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);
    }
}

Este es el C # forma de lograr lo mismo usando el buen ol aburrido interfaces.

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

Como otros han dicho, esto no es realmente disponible en .NET (ya que esto es más una cuestión del tiempo de ejecución de un idioma). Sin embargo, .NET 4.0 admite cosa similar para interfaces COM importados y creo que esto podría ser utilizado para la implementación de la tipificación estructural para .NET. Ver esta entrada del blog:

No traté de jugar con este mismo todavía, pero creo que podría permitir a los autores del compilador para escribir idiomas con la tipificación estructural para .NET. (La idea es que usted (o un compilador) podría definir una interfaz detrás de la escena, pero que iba a funcionar, porque las interfaces serían tratadas como equivalentes gracias a la función de equivalencia COM).

Además, C # 4.0 admite la palabra clave dynamic la que, creo, se podrían interpretar como una tipificación estructural (sin comprobación de tipos estáticos). La palabra clave le permite llamar a métodos en cualquier objeto sin knowning (en tiempo de compilación) si el objeto tendrá los métodos necesarios. Esto es esencialmente lo mismo que el proyecto de "escribir pato" mencionado por Igor (pero eso es, por supuesto, no es una tipificación estructural adecuada).

El patrón awaitable en C # puede quizás ser interpretado como un ejemplo limitado, ad hoc de subtipificación estructural / typing existencial. El compilador sólo await objetos que tienen acceso a un método GetAwaiter() que los retornos cualquier objeto INotifyCompletion con un conjunto específico de métodos y propiedades. Dado que ni el objeto 'awaitable' ni las necesidades de objeto 'awaiter para implementar cualquier interfaz (excepto INotifyCompletion en el caso de este último), await es similar a un método que acepta estructuralmente tecleó objetos awaitable.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top