Si definiera algunos métodos de extensión, propiedades en un ensamblado escrito en F # y luego use ese ensamblaje en C#, ¿verá las extensiones definidas en C#?Métodos de extensión F # en C#
Si es así, sería genial.
Si definiera algunos métodos de extensión, propiedades en un ensamblado escrito en F # y luego use ese ensamblaje en C#, ¿verá las extensiones definidas en C#?Métodos de extensión F # en C#
Si es así, sería genial.
[<System.Runtime.CompilerServices.Extension>]
module Methods =
[<System.Runtime.CompilerServices.Extension>]
let Exists(opt : string option) =
match opt with
| Some _ -> true
| None -> false
Este método podría ser utilizado en C# sólo mediante la adición del espacio de nombres (con el uso) para el archivo donde se va a utilizar.
if (p2.Description.Exists()) { ...}
Here is a link to the original blogpost.
Respondiendo a la pregunta en los comentarios "Extensión métodos estáticos":
namespace ExtensionFSharp
module CollectionExtensions =
type System.Linq.Enumerable with
static member RangeChar(first:char, last:char) =
{first .. last}
En F # que lo llaman así:
open System.Linq
open ExtensionFSharp.CollectionExtensions
let rangeChar = Enumerable.RangeChar('a', 'z')
printfn "Contains %i items" rangeChar.CountItems
En C# se llame como entonces:
using System;
using System.Collections.Generic;
using ExtensionFSharp;
class Program
{
static void Main(string[] args)
{
var method = typeof (CollectionExtensions).GetMethod("Enumerable.RangeChar.2.static");
var rangeChar = (IEnumerable<char>) method.Invoke(null, new object[] {'a', 'z'});
foreach (var c in rangeChar)
{
Console.WriteLine(c);
}
}
}
¡Ahora, dame mi maldita medalla!
Gracias, pero ¿qué pasa con las propiedades de extensión de la instancia y los métodos estáticos, y las propiedades de extensión estática? ¿Serían llamados también? La razón por la que pregunté esto es porque, sé que C# solo tiene métodos de extensión de instancias. –
Gracias, acabo de ver su actualización. –
Definitivamente se merece una medalla por la creatividad con la reflexión y quizás en 2009 esa fue la única forma. Sin embargo, ahora puede usar ['CompiledNameAttribute'] (http://stackoverflow.com/a/39678801/111575) para un enfoque mucho más simple y seguro para llamar a F # desde C#. – Abel
por los language spec, sección 10.7 "Extensiones" Tipo:
miembros de extensión opcionales son el azúcar sintáctica para los miembros estáticos. Los usos de los miembros de extensiones opcionales se complementan con llamadas a miembros estáticos con nombres codificados donde el objeto se pasa como primer argumento. La codificación de nombres no está especificada en esta versión de F # y no es compatible con las codificaciones C# de los miembros de extensión C#
A pesar de mi otra respuesta, simplemente intenté esto con F # CTP (en VS shell) y C# Express desde mi caja en casa (! todas las herramientas dev libres), y esto funciona:
F #
#light
namespace MyFSharp
// C# way
[<System.Runtime.CompilerServices.Extension>]
module ExtensionMethods =
[<System.Runtime.CompilerServices.Extension>]
let Great(s : System.String) = "Great"
// F# way
type System.String with
member this.Awesome() = "Awesome"
let example = "foo".Awesome()
C#
using System;
using MyFSharp; // reference the F# dll
class Program
{
static void Main(string[] args)
{
var s = "foo";
//s.Awesome(); // no
Console.WriteLine(s.Great()); // yes
}
}
yo no era consciente de que podría hacer esto; hábil. Crédito a @alex.
Gracias, ¿pero no es esto solo un método de extensión de instancia? –
Gracias, estaba más interesado en que otras extensiones de F # aparezcan en C#, pero su respuesta de otro tipo aborda eso. –
Por alguna razón, la respuesta aceptada sugiere el uso de la reflexión para obtener un método de extensión de tipo F #. Dado que el nombre del método compilado es diferente entre las versiones de F #, y puede ser diferente según los argumentos, la alineación y otros problemas relacionados con los nombres, prefiero usar CompiledNameAttribute
, que es mucho más fácil y se combina fácilmente con C#. Además, no es necesario reflexionar (y su rendimiento y tipo de problemas de seguridad).
Suponga que tiene esto en C#:
namespace Foo.Bar
module StringExt =
type System.String with
static member ToInteger s = System.Int64.Parse(s)
No sería capaz de llamar a esta directa y la versión compilada se vería así (dependiendo de si hay o no sobrecargas):
namespace Foo.Bar
{
using Microsoft.FSharp.Core;
using System;
[CompilationMapping(SourceConstructFlags.Module)]
public static class StringExt
{
public static long String.ToInteger.Static(string s) =>
long.Parse(s);
}
}
A menos que use la reflexión, no puede acceder al método String.ToInteger.Static
.Sin embargo, una decoración simple método con el CompiledNameAttribute
resuelve este problema:
namespace Foo.Bar
module StringExt =
type System.String with
[<CompiledName("ToInteger")>]
static member ToInteger s = System.Int64.Parse(s)
Ahora el método compilado es la siguiente con reflector, marcan el cambio en el nombre compilado:
namespace Foo.Bar
{
using Microsoft.FSharp.Core;
using System;
[CompilationMapping(SourceConstructFlags.Module)]
public static class StringExt
{
[CompilationSourceName("ToInteger")]
public static long ToInteger(string s) =>
long.Parse(s);
}
}
puede seguir utilizando este método de la forma en que está acostumbrado en F # (como String.ToInteger
en este caso). Pero lo más importante, ahora se puede utilizar este método sin reflexión o de otro engaño de C#:
var int x = Foo.Bar.StringExt.ToInteger("123");
Y, por supuesto, usted puede hacer su vida más fácil mediante la adición de un alias de tipo en C# para el módulo Foo.Bar.StringExt
:
using Ext = Foo.Bar.StringExt;
....
var int x = Ext.ToInteger("123");
Esto no es lo mismo que un método de extensión, y se ignora la decoración del miembro estático con un atributo System.Runtime.CompilerServices.Extension
. Esta es simplemente una forma sencilla de usar type extensions desde otros lenguajes .NET. Si desea un método de extensión "genuino" que parezca actuar según el tipo, use la let
-sintaxis de las otras respuestas aquí.
Véase también http://cs.hubfs.net/forums/thread/13967.aspx – Brian