2013-09-23 37 views
6

Tôi cần viết một cái gì đó mà tôi gọi là Aggregation Container, lưu trữ các tập hợp, về cơ bản là các hành động lấy một tập hợp các đối tượng và xuất ra một đối tượng đơn lẻ. Ví dụ về Tổng hợp sẽ là: Số học trung bình, Trung bình của một tập hợp các số, Hài hòa Trung bình v.v. Dưới đây là mã mẫu.Tập hợp và cách kiểm tra xem chúng ta có thể tổng hợp các đối tượng

var arithmeticMean = new Aggregation 
     { 
      Descriptor = new AggregationDescriptor { Name = "Arithmetic Mean" }, 
      Action = (IEnumerable arg) => 
      { 
       double count = 0; 
       double sum = 0; 

       foreach (var item in arg) 
       { 
        sum += (double)item; 
        count++; 
       } 

       return sum/count; 
      } 
     }; 

Đây là vấn đề của tôi với mã. Tôi đã giả định rằng các đối tượng chỉ là gấp đôi và do đó thực hiện một chuyển đổi. Nếu chúng không gấp đôi thì sao? Làm thế nào tôi có thể chắc chắn rằng tôi được phép tổng hợp hai đối tượng? Có một số loại giao diện cho rằng trong hội đồng tiêu chuẩn .Net? Tôi cần một cái gì đó như ISummable ... Hoặc tôi cần phải thực hiện nó bản thân mình (sau đó tôi sẽ phải bọc tất cả các loại nguyên thủy như đôi, int, etcetera để hỗ trợ nó).

Bất kỳ lời khuyên nào liên quan đến việc thiết kế chức năng như vậy sẽ hữu ích.

+1

Vấn đề không phải là bạn cần xác định xem bộ sưu tập có "tóm tắt" hay không. Tất cả các giá trị số đều vốn có thể tóm tắt. Câu hỏi mà bạn nên hỏi thay vào đó là "Là' arg' một tập hợp các con số? ". Bạn có thể thử cung cấp các biến thể được gõ mạnh mẽ của 'Hành động' cho các kiểu số khác nhau hoặc các phôi thời gian trên' arg'. – Jon

+0

Jon, cảm ơn vì đã trả lời. Tôi biết, các ví dụ tôi đã đưa ra đều là số ... Nhưng tôi thực sự muốn viết một cái gì đó chung chung và hữu ích hơn. Tôi không muốn viết một loạt các phôi thời gian có nhưng tôi đề nghị một tập hợp các hành động với các loại đối số khác nhau sẽ hoạt động ở đây ... –

+3

Hãy xem xét các phương pháp có thể đếm được - nó có tập các phương thức chung được parametrized với từng loại hỗ trợ: 'Sum , Sum , Sum , Tổng >' vv Đó là cách duy nhất để thực hiện tham số kiểu là 'có thể summable' –

Trả lời

3

Hãy xem trên Enumerable phương pháp lớp học - nó đã thiết lập các phương pháp parametrized với từng loại nó hỗ trợ:

int Sum(this IEnumerable<int> source) 
double Sum(this IEnumerable<double> source) 
decimal Sum(this IEnumerable<decimal> source) 
long Sum(this IEnumerable<long> source) 
int? Sum(this IEnumerable<int?> source) 
// etc 

Đó là cách duy nhất để làm cho lập luận phương pháp để được 'summable'.

Thật không may là bạn không thể tạo một số phương pháp chung với generic type parameter constraint, điều này sẽ chỉ cho phép các loại có toán tử + bị quá tải. Không có ràng buộc đối với các toán tử trong .NET, các toán tử cũng không thể là một phần của một số giao diện (do đó chúng là tĩnh). Vì vậy, bạn không thể sử dụng toán tử với các biến kiểu generic.

Ngoài ra nếu bạn sẽ nhìn định nghĩa các kiểu dữ liệu .NET, bạn sẽ không tìm thấy bất kỳ giao diện mà có thể giúp bạn ở đây - chỉ so sánh, định dạng và chuyển đổi được thực hiện:

public struct Int32 : IComparable, IFormattable, IConvertible, 
         IComparable<int>, IEquatable<int> 
0

Bạn có thể thay đổi thuộc tính Action bạn trong lớp như:

public Func<IEnumerable<double>, double> Action { get; set; } 

Vì vậy, nó sẽ chỉ trừ IEnumerable<double> và trả về một kết quả double.

+0

Tôi thực sự đang cố gắng trừu tượng ra khỏi loại bộ sưu tập, để tôi có thể tổng hợp bất kỳ thứ gì có thể được tóm tắt bằng cách nào đó. –

+1

@ george.zakaryan Sau đó, bạn có thể tạo 2 quá tải cho Hành động: 'Hành động (IEnumerable )' và 'Hành động (IEnumerable )' nơi ISummable nên là giao diện của bạn. Double implicitly phôi đến bất kỳ loại số khác. – selfnamed

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