2011-12-18 26 views
18

Có cách nào để khai báo hàm chung chung loại chung loại hoặc type2?Phương pháp chung trong đó T là type1 hoặc type2

dụ như:

public void Foo<T>(T number) 
{ 
} 

Có thể hạn chế T là int hay dài

+1

[ràng buộc trên Loại tham số (Hướng dẫn lập trình C#)] (http://msdn.microsoft.com/en-us/library/d5x73970.aspx) –

+0

@BoltClock, Vì mã của tôi bị ngắt khi tham số không phải là một trong số nguyên thủy (int, dài, gấp đôi ...) và tôi muốn gặp lỗi khi biên dịch không phải trên RunTime – gdoron

+0

Liên quan: [Generic phương pháp nhiều (OR) loại hạn chế] (http://stackoverflow.com/q/10833918) –

Trả lời

12

Bạn có thể sử dụng generic constraints để giới hạn loại đối số chung. Rất tiếc, không có ràng buộc chung nào cho phép bạn thực thi tại thời gian biên dịch cho dù T là type1 or type2. Không có cách nào để thực thi tại thời gian biên dịch mà đối số chung của bạn có thể là bất kỳ kiểu nguyên thủy nào (int, long, double, ...).

7

số

Đó không có ý nghĩa; T sẽ không có bất kỳ loại biên dịch có thể sử dụng nào trong phương thức.

Thay vào đó, bạn nên thực hiện hai phương thức quá tải.

+3

Tôi nghĩ rằng nó có ý nghĩa. Tôi có một mã rằng nếu bạn vượt qua một tham số khác nhau sau đó tăng gấp đôi, thập phân, phao, int, dài vv 'sẽ phanh. Tôi muốn xác minh điều này khi biên dịch. Không có ý nghĩa? – gdoron

+0

@gdoron: Theo quan điểm của bạn, điều đó có ý nghĩa. Từ quan điểm của trình biên dịch, nó không có ý nghĩa, vì 'T' sẽ không phải là một kiểu có thể sử dụng được. – SLaks

+0

Trong trường hợp này trình biên dịch có thể xử lý 'T' là kiểu chung của type1 và type2, trong đó không có quan hệ' T' là 'đối tượng' ... – gdoron

0

Tôi không nghĩ rằng điều này là hiện tại có thể.

This question về cách tạo loại thư viện toán học bao gồm cùng một nền tảng và bao gồm một số công việc xung quanh.

4

Sử dụng quá tải phương pháp thay vì:

public void Foo(int number) 
{ 
} 

public void Foo(long number) 
{ 
} 

Bạn không thể thực hiện thao tác số học trên các loại generic anyway. Lưu ý rằng bạn có thể chuyển giá trị int cho tham số long. Nó sẽ tự động được chuyển đổi thành long. Chỉ có một phương pháp duy nhất với tham số long có thể là đủ.

Ngôn ngữ lập trình cũ hơn hoạt động sau nguyên tắc "Chỉ có thể có một". C# cho phép bạn có một số phương thức có cùng tên trong cùng một lớp, giao diện hoặc cấu trúc. Các phương thức này phải có chữ ký khác. Điều này có nghĩa, rằng chúng phải có một số thông số hoặc tham số khác nhau với các loại khác nhau (hoặc cả hai). Điều này được gọi là quá tải phương thức.

+0

Tôi không thể viết 20 phương thức cho mỗi loại giá trị số. đây là những gì Generics ** nên có ** giải quyết – gdoron

+0

Phép toán số học không được hỗ trợ trên các tham số kiểu chung. Xem 'System.Text.StringBuilder' để biết ví dụ. Nó định nghĩa hơn 20 'Append()' overload cho các kiểu differents. –

0

Tôi biết đây là câu hỏi cũ và điều này không hoàn toàn trả lời, nhưng bạn có thể làm điều này bằng một phương pháp duy nhất, thay vì tạo bội số hoặc sử dụng các ràng buộc chung ... đặc biệt hữu ích nếu bạn có 20 kỳ quặc loại để kiểm tra.

Rõ ràng bạn không bị loại trình biên dịch kiểm tra như bạn làm khi sử dụng một hạn chế, nhưng điều này có thể giúp đỡ trong một số trường hợp ...

public void MyMethod<T>() 
{ 
    if (!typeof(T).Equals(typeof(int)) && 
     !typeof(T).Equals(typeof(long))) 
      throw new Exception("T must be int or long"); 

    //your logic here 
} 
0

Tôi cũng có vấn đề này và tôi nghĩ rằng tôi tìm thấy một giải pháp tốt hơn (giả định một phiên bản quá tải của phương thức của bạn là không đủ):

Trộn Type1Type2 mà không có bất kỳ điểm tương đương nào không có ý nghĩa như đã được viết. Vì vậy, phải có bất kỳ phương thức hoặc thuộc tính nào được truy cập cho cả hai loại đối tượng.Để đảm bảo cho các trình biên dịch rằng những phương pháp hoặc tài sản có sẵn cho đối tượng của bạn, nhóm Type1Type2 bằng cách tạo ra một giao diện MyInterface và thực hiện nó bằng cách Type1Type2:

interface MyInterface { 
    void MyCommonMethod(); 
    bool MyCommonProperty { get; } 
} 

class Type1 : MyInterface { 
    void MyCommonMethod() { 
    // TODO: Implement it for Type1 
    } 

    bool MyCommonProperty { 
    get { 
    // TODO: Implement it for Type1 
    } 
    } 
} 

class Type2 : MyInterface { 
    void MyCommonMethod() { 
    // TODO: Implement it for Type2 
    } 

    bool MyCommonProperty { 
    get { 
    // TODO: Implement it for Type2 
    } 
    } 
} 

Bây giờ, để viết lại phương pháp Foo bạn để chấp nhận cả Type1Type2, hạn chế T trở thành một đối tượng MyInterface:

public void Foo<T>(T number) where T : MyInterface 
{ 
    throw new NotImplementedException(); 
} 

tôi Mope này có thể hữu ích. :)

6

Đối ReferenceType đối tượng bạn có thể làm

public void DoIt<T>(T someParameter) where T : IMyType 
{ 

} 

...

public interface IMyType 
{ 
} 

public class Type1 : IMyType 
{ 
} 

public class Type2 : IMyType 
{ 
} 

Đối với trường hợp của bạn sử dụng miễn là tham số sẽ hạn chế sử dụng để chờ đợi và ints anyway.

public void DoIt(long someParameter) 
{ 

} 

để hạn chế đối với bất kỳ kiểu giá trị (như: int, double, ngắn, số thập phân), bạn có thể sử dụng:

public void DoIt<T>(T someParameter) where T : struct 
{ 

} 

để biết thêm thông tin bạn có thể kiểm tra tài liệu chính thức here

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