2010-06-25 14 views
47

En C# se puede escribir:equivalente de Scala de los métodos de extensión de C#?

using System.Numerics; 
namespace ExtensionTest { 
public static class MyExtensions { 
    public static BigInteger Square(this BigInteger n) { 
     return n * n; 
    } 
    static void Main(string[] args) { 
     BigInteger two = new BigInteger(2); 
     System.Console.WriteLine("The square of 2 is " + two.Square()); 
    } 
}} 

¿Cómo sería este sencillo extension method verá como en Scala?

Respuesta

60

El patrón Pimp My Library es la construcción análoga:

object MyExtensions { 
    implicit def richInt(i: Int) = new { 
    def square = i * i 
    } 
} 


object App extends Application { 
    import MyExtensions._ 

    val two = 2 
    println("The square of 2 is " + two.square) 

} 

los comentarios de Per @ Daniel SPIEWAK, esto evitará la reflexión sobre la invocación de métodos, el rendimiento ayudando:

object MyExtensions { 
    class RichInt(i: Int) { 
    def square = i * i 
    } 
    implicit def richInt(i: Int) = new RichInt(i) 
} 
+28

Advertencia: mediante el uso de la nueva '' {...} sintaxis, que en realidad estás haciendo que el compilador para inferir un tipo estructural para el método 'richInt', significado que cualquier invocación de 'cuadrado' se hará usando reflexión (un asesino de rendimiento). Sería mejor definir una clase 'RichInt' que define' square' y se devuelve del método 'richInt'. –

+0

@Daniel, ¿podría publicar el código que está describiendo? – OscarRyz

+4

@Support Agregue 'clase RichInt (i: Int) {def square = i * i}' a 'MyExtensions' y ejecute' new RichInt (i) 'en el método' richInt'. –

3

En Scala usamos el llamado (por el inventor del lenguaje) Pimp My Library patrón, que es muy discutido y bastante ea sy buscar en la Web, si usa una búsqueda de cadenas (no palabras clave).

9

Este sería el código después de Daniel comment.

object MyExtensions { 
    class RichInt(i: Int) { 
     def square = i * i 
    } 
    implicit def richInt(i: Int) = new RichInt(i) 

    def main(args: Array[String]) { 
     println("The square of 2 is: " + 2.square) 
    } 
} 
45

Desde la versión 2.10 de Scala, es posible hacer una clase entera elegibles para conversión implícita

implicit class RichInt(i: Int) { 
    def square = i * i 
} 

Además, es posible evitar la creación de una instancia del tipo de extensión por tener que extender AnyVal

implicit class RichInt(val i: Int) extends AnyVal { 
    def square = i * i 
} 

Para obtener más información sobre las clases implícitas y AnyVal, limitaciones y peculiaridades, consultar la documentación oficial:

+0

Tenga en cuenta que las clases de casos ** no pueden ** anotarse con la palabra clave 'implicit', ya que tienen un objeto complementario generado automáticamente. Para obtener más información, consulte los enlaces de documentación proporcionados por @megri. – falconepl

Cuestiones relacionadas