2016-06-29 17 views
10

Tôi thực sự thích kiểu số chung như tham số kiểu chung thứ hai của số Func<TInput, THere, TResult> được đưa ra dưới đây để tôi có thể cung cấp số nguyên hoặc số double hoặc số thập phân và khi tôi muốn.Có loại số chung trong C# không?

var _resultSelectors = new Dictionary<string, Func<DateTime, /*here*/ double, DateTime>>(); 

// so I can do 
_resultSelector.Add("foo", (DateTime dt, int x) => ...); 
_resultSelector.Add("bar", (DateTime dt, double d) => ...); 
_resultSelector.Add("gar", (DateTime dt, float f) => ...); 
_resultSelector.Add("har", (DateTime dt, decimal d) => ...); 

ngắn của:

  1. làm kiểu của riêng tôi; hoặc
  2. sử dụng đối tượng và đấm bốc một loại giá trị và bỏ hộp đó; hoặc
  3. Sử dụng từ khóa dynamic,

Có một cách thích hợp để làm điều đó trong C#?

Tôi đoán Java có một lớp học Number có thể phù hợp với yêu cầu của tôi nhưng tôi đã tự hỏi liệu C# có bất kỳ điều gì tương tự không.

Tôi đoán không có bất kỳ điều nào trong C# nhưng tôi nghĩ rằng tôi sẽ yêu cầu chắc chắn.

+0

Nếu bạn có thể có tất cả 4, tôi khuyên bạn nên chọn một 'double' hoặc 'decimal' (tùy thuộc vào trường hợp sử dụng của bạn, tức là dấu phẩy động) và chuyển phần còn lại thành số đó. –

+0

@CharlesMager Đó là một ý tưởng hay. –

+0

Không có giao diện chung nhưng bạn vẫn gặp sự cố khi tìm các func chính xác để gọi dựa trên kiểu thời gian chạy của giá trị. Giá trị số cụ thể đến từ đâu? – Lee

Trả lời

11

Không, không có. Các phép toán học và số học (+, -, *, /, v.v.) không làm việc cùng nhau. Đây là một vấn đề được đưa lên nhiều lần và thiết kế C# comitee chưa bao giờ giải quyết (để công bằng, tính năng này cũng cần phải làm việc trên CLR, như được chỉ ra bởi Eric Lippert trong câu trả lời liên kết thêm).

Nghiêm túc, nếu bạn kiểm tra mã nguồn của .NET Framework bạn sẽ thấy rằng trong một số giai đoạn phát triển có giao diện IArithmetic<T>, nhưng nó đã bị loại bỏ; xem here.

Bạn có thể đọc thêm về điều này, trong số SO answer này.

5

Thậm chí nếu có loại cơ sở hoặc giao diện bao gồm các loại số, vì bạn đã bao bọc ràng buộc trong một Func, nó sẽ không làm bạn tốt. các kiểu đầu vào cho Func là contravariant, vì vậy các tham số của nó không thể bắt nguồn từ những gì được khai báo.

Nói cách khác, bạn không thể thay thế một Func<DateTime, ValueType, DateTime> với một Func<DateTime, int, DateTime> như bạn có thể với IEnumerable<T> (bạn có thể thay thế một IEnumerable<ValueType> với một IEnumerable<int>)

Tôi nghĩ cược tốt nhất của bạn là dynamic (vẫn gõ an toàn , nhưng vào thời gian chạy so với biên dịch) hoặc double hoặc decimal nếu bạn muốn làm toán và không phải ở cùng loại.

+0

'Func' có phương sai. Các tham số đầu vào của nó là contravariant và đầu ra của nó là covariant. Đây là định nghĩa về quá tải đặc biệt mà tôi sử dụng: public 'delegate TResult Func (T1 arg1, T2 arg2); ' –

+0

Oh xin lỗi tôi đã đọc lại tin nhắn của bạn một lần nữa. Bạn đúng. Bởi vì các contravariance của các loại đầu vào của nó, các tham số chung đóng thực tế không thể có nguồn gốc nhiều hơn so với các loại thời gian biên dịch của họ. –

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