Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# C语言中的F#延拓方法#_C#_F#_Extension Methods - Fatal编程技术网

C# C语言中的F#延拓方法#

C# C语言中的F#延拓方法#,c#,f#,extension-methods,C#,F#,Extension Methods,如果要在用F#编写的程序集中定义一些扩展方法和属性,然后在C#中使用该程序集,您会看到在C#中定义的扩展吗 如果是这样,那就太酷了 [<System.Runtime.CompilerServices.Extension>] module Methods = [<System.Runtime.CompilerServices.Extension>] let Exists(opt : string option) =

如果要在用F#编写的程序集中定义一些扩展方法和属性,然后在C#中使用该程序集,您会看到在C#中定义的扩展吗

如果是这样,那就太酷了

[<System.Runtime.CompilerServices.Extension>]
module Methods =   
    [<System.Runtime.CompilerServices.Extension>]   
    let Exists(opt : string option) =                
    match opt with
       | Some _ -> true                  
       | None -> false

回答评论“扩展静态方法”中的问题:

在F#中,你这样称呼它:

open System.Linq 
open ExtensionFSharp.CollectionExtensions 

let rangeChar = Enumerable.RangeChar('a', 'z') 
printfn "Contains %i items" rangeChar.CountItems
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);
            }
        }
    }
在C#中,你这样称呼它:

open System.Linq 
open ExtensionFSharp.CollectionExtensions 

let rangeChar = Enumerable.RangeChar('a', 'z') 
printfn "Contains %i items" rangeChar.CountItems
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);
            }
        }
    }
使用系统;
使用System.Collections.Generic;
使用ExtensionFSharp;
班级计划
{
静态void Main(字符串[]参数)
{
var method=typeof(CollectionExtensions).GetMethod(“Enumerable.RangeChar.2.static”);
var rangeChar=(IEnumerable)方法。Invoke(null,新对象[]{'a','z'});
foreach(rangeChar中的变量c)
{
控制台写入线(c);
}
}
}
现在,把我那该死的奖章给我

根据第10.7节“类型扩展”:


可选扩展成员是静态成员的语法糖。使用可选扩展成员可以详细描述对具有编码名称的静态成员的调用,其中对象作为第一个参数传递。这个版本的F#中没有指定名称的编码,并且与C#扩展成员的C#编码不兼容

尽管我有其他答案,但我只是在家里的盒子里用F#CTP(在VS外壳上)和C#Express(所有免费开发工具!)尝试了这个方法,这是可行的:

F#


我不知道你能做到这一点;漂亮。要归功于@alex。

出于某种原因,公认的答案建议使用反射来获得F类型的扩展方法。由于不同版本的F#的编译方法名称不同,并且可能因参数、内联和其他命名相关问题而有所不同,因此我建议改为使用,因为它更容易与C#混合。此外,无需考虑(及其性能和类型安全问题)

假设你在F#中有这个:

您将无法直接调用它,编译后的版本将如下所示(取决于是否存在重载):

除非使用反射,否则无法访问方法
String.ToInteger.Static
。然而,一种简单的装饰方法解决了这个问题:

namespace Foo.Bar
module StringExt =
    type System.String with
        [<CompiledName("ToInteger")>]
        static member ToInteger s = System.Int64.Parse(s)
您仍然可以按照在F#中使用的方式使用此方法(在本例中为
String.ToInteger
)。但更重要的是,您现在可以使用此方法,而无需使用C#的反射或其他诡计:

当然,您可以通过在C#中为
Foo.Bar.StringExt
模块添加一个类型别名来简化您的工作:

using Ext = Foo.Bar.StringExt;
....
var int x = Ext.ToInteger("123");

这与扩展方法不同,使用
System.Runtime.CompilerServices.extension
属性装饰静态成员会被忽略。这只是从其他.NET语言使用的一种简单方法。如果您想要一个对类型起作用的“真正”扩展方法,请使用此处其他答案中的
let
-语法。

谢谢,但是实例扩展属性和静态方法以及静态扩展属性呢?他们也会被叫来吗?我问这个问题的原因是因为,我知道C#只有实例扩展方法。你肯定应该为反射的创造性方法获得一枚奖章,也许在2009年,这是唯一的方法。但是,您现在可以使用一种更简单且类型安全的方法从C#调用F#。谢谢,但这不只是一种实例扩展方法吗?谢谢,我对在C#中出现的F#的其他扩展更感兴趣,但是你的另一个回复是这样的。你知道有没有计划统一F和C实现类型扩展的方法。如果不需要使用额外的属性,那就太好了。看起来我们不会在F#的第一个版本中这样做(例如,不在VS2010时间范围内)。另请参见
namespace Foo.Bar
module StringExt =
    type System.String with
        static member ToInteger s = System.Int64.Parse(s)
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);
    }
}
namespace Foo.Bar
module StringExt =
    type System.String with
        [<CompiledName("ToInteger")>]
        static member ToInteger s = System.Int64.Parse(s)
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);
    }
}
var int x = Foo.Bar.StringExt.ToInteger("123");
using Ext = Foo.Bar.StringExt;
....
var int x = Ext.ToInteger("123");