Vì một số lý do, câu trả lời được chấp nhận đề xuất sử dụng phản chiếu để có phương thức mở rộng loại F #. Vì tên phương thức được biên dịch khác nhau giữa các phiên bản của F # và có thể khác nhau tùy thuộc vào các đối số, nội tuyến và các vấn đề đặt tên khác, tôi muốn thay vì sử dụng CompiledNameAttribute
, dễ dàng hơn và dễ dàng hòa trộn với C#. Bên cạnh đó, không cần sự phản ánh (và các vấn đề an toàn về hiệu suất và loại của nó).
Giả sử bạn có điều này trong F #:
namespace Foo.Bar
module StringExt =
type System.String with
static member ToInteger s = System.Int64.Parse(s)
Bạn sẽ không thể gọi đây là trực tiếp và phiên bản biên soạn sẽ trông như thế này (tùy thuộc vào có hay không có quá tải):
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);
}
}
Trừ khi bạn sử dụng phản chiếu, bạn không thể truy cập phương thức String.ToInteger.Static
.Tuy nhiên, một phương pháp trang trí đơn giản với CompiledNameAttribute
giải quyết vấn đề này:
namespace Foo.Bar
module StringExt =
type System.String with
[<CompiledName("ToInteger")>]
static member ToInteger s = System.Int64.Parse(s)
Bây giờ phương pháp biên soạn trông như thế này trong Reflector, đánh dấu sự thay đổi trong tên biên soạn:
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);
}
}
Bạn vẫn có thể sử dụng này phương pháp theo cách bạn đang sử dụng trong F # (như String.ToInteger
trong trường hợp này). Nhưng quan trọng hơn, bây giờ bạn có thể sử dụng phương pháp này mà không suy nghĩ hoặc thủ đoạn gian trá khác từ C#:
var int x = Foo.Bar.StringExt.ToInteger("123");
Và dĩ nhiên, bạn có thể làm cho cuộc sống của bạn đơn giản bằng cách thêm một loại bí danh trong C# cho Foo.Bar.StringExt
mô-đun:
using Ext = Foo.Bar.StringExt;
....
var int x = Ext.ToInteger("123");
Điều này không giống như một phương pháp mở rộng và trang trí thành viên tĩnh với thuộc tính System.Runtime.CompilerServices.Extension
bị bỏ qua. Đây chỉ là một cách đơn giản để sử dụng type extensions từ các ngôn ngữ .NET khác. Nếu bạn muốn phương thức tiện ích mở rộng "chính hãng" có vẻ hoạt động trên loại, hãy sử dụng let
-syntax từ các câu trả lời khác tại đây.
Xem thêm http://cs.hubfs.net/forums/thread/13967.aspx – Brian