2009-04-08 17 views
6

Tôi đang cố thêm một ràng buộc vào một phương thức chung để nó kiểm tra các kiểu giá trị ValueTypes, Strings hoặc Nullable.Ràng buộc chung đối với ValueTypes, Strings và Nullable của ValueTypes

Vấn đề là:

  • kiểu giá trị là thanh chống
  • chuỗi là các loại tài liệu tham khảo không thay đổi
  • nullable là kiểu giá trị nhưng sẽ không được chấp nhận trong một "trong đó S: struct" loại hạn chế .

Vì vậy, không ai biết nếu có cách nào tôi có thể chấp nhận những điều này và chỉ những loại này trong một hạn chế chung?

Vấn đề là tôi đang cố gắng chấp nhận tham số Expression<Func<T, S> sẽ đại diện cho thuộc tính của các loại này cho một đối tượng nhất định.

Các chức năng sẽ giống như sau (lưu ý mã số không có ý nghĩa gì và chỉ là một cái gì đó nhanh chóng để có được một ý tưởng về những gì tôi đang tìm kiếm):

public class Person 
{ 
    public string Name {get; set;} 
    public DateTime? DOB {get; set;} 
    public int NumberOfChildren {get; set;} 
    public Car CurrentCar {get; set;} 
} 

--- 

internal void MyGenericMethod<T, S>(T myObject, Expression<Func<T, S> property){...} 

Person myPerson = new Person(); 
MyGenericMethod(myPerson, p => p.Name); //S would be a string 
MyGenericMethod(myPerson, p => p.DOB); //S would be a DateTime? 
MyGenericMethod(myPerson, p => p.NumberOfChildren); //S would be a struct 

Ba cuộc gọi trên tất cả nên được chấp nhận, nhưng không phải như sau:

MyGenericMethod(myPerson, p => p.CurrentCar); //S would be a class and shouldn't compile 

Cảm ơn trước

UPDATE: Cảm ơn Anton và Marc. MyGenericMethod có 4 chữ ký khác nhau chấp nhận các tham số phụ, đó là lý do tại sao tôi không thích ý tưởng tạo 3 khác nhau (struct, nullable, string) cho mỗi 4 hiện có ... đó sẽ là một cơn ác mộng để duy trì!

Trả lời

7

Điều duy nhất tôi có thể đưa ra là một tập hợp ba chức năng (sans Expression<> thứ):

MyGenericFunction<T>(T t) 
    where T : struct 

MyGenericFunction<T>(T? t) 
    where T : struct 

MyGenericFunction(string s) 

CẬP NHẬT Cho rằng có quá tải khác nhau của một phương pháp, tôi có thể đề nghị:

class Holder 
{ 
    private object value; 

    public Holder(object value) 
    { 
     this.value = value; 
    } 

    public static implicit operator Holder(DateTime dt) 
    { 
     return new Holder(dt); 
    } 

    public static implicit operator Holder(string s) 
    { 
     return new Holder(s); 
    } 

    // Implicit conversion operators from primitive types 
} 

Vì vậy phương pháp của bạn trở nên

MyGenericMethod(Holder h); 

Vẫn còn rất cồng kềnh, nhưng tuy nhiên nó có thể làm việc ra ngoài.

+0

Có thể có ý nghĩa để xác định 'struct Holder' thay thế. Sau đó, nó trở thành "đường cú pháp" biên dịch, với mục đích là để xác định cái gì là và không hợp pháp. Nhưng kết quả thời gian chạy sẽ hiệu quả - loại bỏ việc phân bổ/thu gom rác cần thiết cho một lớp. – ToolmakerSteve

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