2011-01-08 36 views
16

Có điều gì tương tự với mẫu C++ này không?C# generic với hằng số

template <int A> 
class B 
{ 
    int f() 
    { 
     return A; 
    } 
} 

Tôi muốn làm cho mỗi thể hiện của B < 1>, B < 2>, vv (ví dụ tuple) một kiểu khác nhau.

Trả lời

18

Câu trả lời ngắn gọn là không.

Nó không phù hợp với cách C# generics, như apposed để C + + mẫu, công việc.

Các generic .net không phải là một tính năng ngôn ngữ, chúng là một tính năng thời gian chạy. Thời gian chạy biết làm thế nào để khởi tạo generics từ bytecode chung đặc biệt mà là khá hạn chế so với những gì C + + mẫu có thể mô tả.

So sánh điều này với các mẫu C++, về cơ bản này sẽ khởi tạo toàn bộ AST của lớp bằng cách sử dụng các loại thay thế. Có thể thêm instantiation dựa trên AST vào thời gian chạy, nhưng nó chắc chắn sẽ phức tạp hơn nhiều so với các generics hiện tại.

Nếu không có các tính năng như mảng kiểu giá trị (chỉ tồn tại trong mã không an toàn), thì mẫu đệ quy hoặc mẫu chuyên biệt bằng cách sử dụng các tham số đó cũng sẽ không hữu ích.

+1

Vâng, tại thời gian chạy (JIT) .Net làm cho việc khởi tạo. Instantiation về cơ bản là trùng lặp với các sửa đổi. Tôi sẽ không phản đối AST tới MSIL nhiều. Đại diện khác nhau của các khái niệm tương tự. –

12

C# không hỗ trợ các tham số chung không kiểu như C++.

C# generics đơn giản hơn và ít có khả năng hơn so với mẫu C++. MSDN có danh sách ngắn gọn là Differences Between C++ Templates and C# Generics.

+1

Tuy nhiên, biết thêm chi tiết có thể được " được mã hóa thành các loại (theo định nghĩa hợp đồng hoặc bằng cách khác), thật đơn giản để xem với một số loại kín đáo (ví dụ: Vn: V, nơi Vn.Value = n cho tất cả VN'), nhưng cũng có [số nhà thờ] (http://community.bartdesmet.net/blogs/bart/archive/2009/08/17/mis-using-c-4-0-dynamic-type-free-lambda-calcul us-church-numerals-and-more.aspx) - không phải là tôi đề nghị * hoặc cách tiếp cận * ở đây :-) –

+1

Không phải là một câu trả lời sai, nhưng nó sẽ được tốt đẹp nếu nó cung cấp một liên kết đến C# generics và/hoặc nói về tuyên bố chung/"instantiation" so với instantiation mẫu. –

+3

@pst: Chắc chắn; bạn có thể mã hóa thông tin thành các loại. Bạn cũng có thể tránh các generics hoàn toàn và viết rất nhiều các lớp học nongeneric. Trong bất kỳ trường hợp nào; Tôi đã thêm một liên kết đến bài viết MSDN liệt kê sự khác biệt lớn giữa các mẫu và Generics. –

5

C# generics chuyên về thời gian chạy, trong khi mẫu C++ được xử lý tại thời gian biên dịch để tạo một loại hoàn toàn mới. Do đó, thời gian chạy đơn giản không có các tính năng để xử lý các tham số không phải kiểu (nó không chỉ là một vấn đề C#).

8

Một cách giải quyết để hạn chế này là để xác định một lớp mà tự nó cho thấy nhiều giá trị văn chương mà bạn quan tâm Ví dụ:.

public interface ILiteralInteger 
{ 
    int Literal { get; } 
} 

public class LiteralInt10 : ILiteralInteger 
{ 
    public int Literal { get { return 10; } } 
} 

public class MyTemplateClass<L> where L: ILiteralInteger, new() 
{ 
    private static ILiteralInteger MaxRows = new L(); 

    public void SomeFunc() 
    { 
     // use the literal value as required 
     if(MaxRows.Literal) ... 
    } 
} 

Cách sử dụng:

var myObject = new MyTemplateClass<LiteralInt10>();