2015-06-16 28 views
7

Câu hỏi này không tương thích về C#/F # như trong this one.Thực hiện đúng F # Unit trong C#

Tôi muốn biết cách thích hợp để triển khai loại như F# Unit thay vì sử dụng void.

Rõ ràng là tôi sẽ hủy kết quả này và tôi sẽ không để lộ loại này cho thế giới bên ngoài.

Tự hỏi liệu một lớp trống có thể mạo danh vai trò này hay không.

internal class Unit 
{ 
} 

Ví dụ: trong thư viện language-ext, tác giả đã sử dụng struct.

Có lợi ích nào trong lựa chọn này không?

+0

Giá trị cấu trúc và giá trị lớp luôn là gần như giống nhau về hiệu suất, nhưng giá trị cũ có thể bị giới hạn ở một giá trị số ít trong khi giá trị thứ hai không thể (không và không null). 'Đơn vị lớp trừu tượng bên trong 'sẽ là một ý tưởng tốt hơn ... – ildjarn

+7

Bạn có thể quan tâm đến việc triển khai RX: https://github.com/Reactive-Extensions/Rx.NET/blob/master/Rx.NET/Source/ System.Reactive.Core/Reactive/Unit.cs – Foole

+0

@idjarn, xin lỗi tôi đã không hiểu những gì bạn có nghĩa là ... Bạn đang nói rằng một loại giá trị là tốt hơn bởi vì không thể được thiết lập để 'null' (nếu không được đóng hộp một cách rõ ràng)? – gsscoder

Trả lời

6

Tôi không chắc chắn cách tốt nhất để xác định Unit để sử dụng từ C# là gì. Nó có thể khác với cách thức này được thực hiện trong F # (vì trong F #, trình biên dịch ẩn cách sử dụng theo cách này).

Tuy nhiên, bạn có thể thực sự tìm ra thi hành F # unit trong thư viện lõi:

Dưới đây là những điểm mấu chốt về F # unit thực hiện

  • Nó thực hiện ents GetHashCodeEquals trong cùng một cách với phiên bản Rx
  • Đó là IComparable và tất cả các giá trị của các loại unit đều bình đẳng
  • Quan trọng nhất, nó có một nhà xây dựng tư nhân và do đó bạn không thể tạo ra một giá trị mới unit. Nó cũng không có trường hợp mặc định (không giống như đơn vị Rx) và như vậy trong F #, tất cả các giá trị đơn vị thực sự được biểu thị là null. Tuy nhiên, ngôn ngữ/trình biên dịch thường ẩn thực tế này.

Vì vậy, có vẻ như sự khác biệt duy nhất trong F # là nó sử dụng giá trị null. Nếu bạn muốn sử dụng unit một cách rõ ràng, điều này có thể không phải là lựa chọn tốt nhất. Tuy nhiên, nếu bạn có Unit.Default sau đó bạn đang cuối cùng xác định một loại với hai giá trị có thể, bởi vì nó có thể là Unit.Default hoặc null (và do đó nó không phải là thực sự là một đơn vị!)

+0

+1 Câu trả lời cho câu hỏi và điểm của tôi bởi @Tomas Petricek đã làm mọi việc rõ ràng hơn. Tôi cũng đánh giá cao các liên kết đến nguồn F #: thú vị và hữu ích. Tôi chỉ là một điều cuối cùng để hỏi: trong câu cuối cùng bạn nói rằng giá trị có thể là 'Unit.Default' hoặc' null'; nhưng nếu tôi định nghĩa (giống như trong Rx) kiểu là 'struct' thì nó không thể là' null' nếu không được đóng gói một cách rõ ràng. Đúng? Dù sao một lần được xác định (ví dụ: bên trong thư viện có thể sử dụng lại), tôi sẽ không hiển thị thông tin này cho ** API công cộng **; Tôi lập kế hoạch (ví dụ) để xác định 'Func ' thay vì 'Hành động ' (khi hoàn toàn bắt buộc và tác dụng phụ không thể tránh được). – gsscoder

+1

@gsscoder: "* nhưng nếu tôi định nghĩa (giống như trong Rx), kiểu đó là' struct', nó không thể là 'null' nếu không được đóng hộp một cách rõ ràng. Phải không? *" Er, nếu đối tượng của kiểu giá trị được đóng hộp, sau đó nó sẽ là kiểu 'obj' kiểu runtime và nó sẽ không là null - các kiểu giá trị không thể là null, period (do đó tồn tại' System.Nullable <> 'để mô phỏng kiểu này). Trong mọi trường hợp, ông chỉ nhận xét về lý do tại sao F # không có một hàm tạo có thể truy cập hay bất cứ thứ gì như 'Unit.Default' (vì F # _doesn't_ sử dụng một cấu trúc). – ildjarn

+0

@ildjarn +1 để làm rõ thêm, được hiểu hoàn toàn ngay bây giờ ... – gsscoder

1

System.ValueTuple (mà không cần tranh luận chung) là rất nhiều đơn vị trong C#. The source code đang mở.

Các vấn đề liên quan