2008-10-26 48 views
31

Cụ thể, có thể có mã số tương tự mã C++ này được thực hiện tại thời gian biên dịch trong C# không?Có thể lập trình meta trong C# không?

template <int N> 
struct Factorial 
{ 
    enum { value = N * Factorial<N - 1>::value }; 
}; 

template <> 
struct Factorial<0> 
{ 
    enum { value = 1 }; 
}; 

// Factorial<4>::value == 24 
// Factorial<0>::value == 1 
void foo() 
{ 
    int x = Factorial<4>::value; // == 24 
    int y = Factorial<0>::value; // == 1 
} 
+5

Mặc dù không thể thực hiện được bằng C#, nhưng có thể có các ngôn ngữ .NET được chọn mạnh như [Boo] (http://boo.codehaus.org/) và [Nemerle] (http://nemerle.org/Main_Page)). –

+1

Bạn có thể đọc Metaprogramming trong .NET http://www.manning.com/hazzard của Kevin Hazzard và Jason Bock –

+0

@ Jordão: Boo là một ngôn ngữ rất khác và Nemerle ít nhiều chết vì Jetbrains đã thuê bộ não. Có lẽ Script.NET đáng được đề cập đến. –

Trả lời

30

Không, lập trình meta của sự phức tạp này không được ngôn ngữ C# hỗ trợ trực tiếp. Tuy nhiên, như @littlegeek cho biết, Text Template Transformation Toolkit đi kèm với Visual Studio sẽ cho phép bạn đạt được sự tạo mã của bất kỳ sự phức tạp nào.

+0

không có vấn đề gì nhỏ; tôi đã bình chọn cho bạn để đánh bại tôi 4 giờ thậm chí không có Clipboard :) –

+0

Rất tuyệt, cảm ơn. –

+0

Liên kết 'Bộ công cụ chuyển đổi mẫu văn bản' bị hỏng, hãy thử liên kết này thay thế: http://wekeroad.com/2008/10/13/make-visual-studio-generate-your-repository/ –

6

Không, không thể lập trình meta trong C#.

+2

tại sao downvote, đó là buồn cười! – GogaRieger

3

Để rất phạm vi giới hạn, C# điều gì đó có thể được hiểu là lập trình meta. Nhưng thực sự nó không có gì hơn là độ phân giải quá tải. Đó là một trải nghiệm thực sự để gọi nó là lập trình meta.

Ví dụ:

static string SomeFunc<T>(T value) { 
    return "Generic"; 
} 
static string SomeFunc(int value) { 
    return "Non-Generic"; 
} 

static void Example() { 
    SomeFunc(42);   // Non-Generic 
    SomeFunc((object)42); // Generic 
} 
+1

Tôi thích bị bỏ phiếu không có lý do hoặc nhận xét. – JaredPar

+2

Người hỏi đã không thực sự xác định ý nghĩa của chúng bằng Metaprogramming, nhưng tôi nghĩ rằng nó an toàn để nói rằng nó khác với ý của bạn. – Anthony

+0

@Anthony, vấn đề với các câu hỏi mơ hồ là chúng tạo ra các câu trả lời sai hoặc không có ý nghĩa. Tôi không thể trả lời câu hỏi hoặc cung cấp câu trả lời có thể trả lời câu hỏi. Miễn là tôi ở đây, tôi hình tôi cũng có thể trả lời :) – JaredPar

9

loại cái nhìn đối với các mẫu t4

Xin lỗi trên iphone và không thể trỏ đến tài nguyên.

Scott Hansleman đã đăng tuần trước về nó.

+9

Đây chính là lý do tại sao SO cần một phiên bản iPhone đặc biệt. – Kredns

4

Sự khác biệt cơ bản giữa .NET Generics và C++ Templates là generics chuyên về thời gian chạy. Các mẫu được mở rộng tại thời gian biên dịch. Các hành vi năng động của generics làm cho những thứ như Linq, biểu hiện cây, Type.MakeGenericType(), ngôn ngữ độc lập và tái sử dụng mã có thể.

Nhưng có một mức giá, bạn không thể ví dụ sử dụng toán tử trên các giá trị của đối số loại chung. Bạn không thể viết std :: class phức tạp trong C#. Và không có lập trình meta thời gian biên dịch.

+0

Tôi biết bằng kinh nghiệm có thể sử dụng lại mã mẫu. Và cái gọi là "ngôn ngữ độc lập" mà bạn đang đề cập đến thực sự có nghĩa là bạn phải sử dụng ngôn ngữ tuân thủ .net ... Có những hạn chế đối với cả hai .net generics cũng như C++ templates. Nhưng đây không phải là những cái đúng. –

+0

Và tất nhiên, bạn có thể viết một lớp số phức tạp (hoặc tốt hơn, một cấu trúc) trong C#, nhưng các thư viện mẫu thực hiện các phép tính trên các tham số kiểu số khó viết và sử dụng, xem http://www.codeproject.com /KB/cs/genericnumerics.aspx và http://www.codeproject.com/KB/cross-platform/BenchmarkCppVsDotNet.aspx – Qwertie

+0

"Bạn không thể viết std :: class phức tạp trong C#". Theo nghĩa nào? –

6

Bạn phải cẩn thận khi nói về thời gian biên dịch khi giao dịch với ngôn ngữ Java hoặc .Net. Trong những ngôn ngữ đó bạn có thể thực hiện metaprogamming mạnh hơn (theo nghĩa rộng hơn - phản ánh-) so với C++ do thực tế là "thời gian biên dịch" (JIT) có thể bị trì hoãn sau "thời gian chạy";)

4

Nó sẽ để có thể. Xem bài diễn văn của The Future of C# của Anders Hejlsberg.

6

Hầu hết mọi người nhấn mạnh vào việc cố gắng lập trình meta từ bên trong ngôn ngữ yêu thích của họ. Điều đó không hiệu quả nếu ngôn ngữ không hỗ trợ lập trình meta tốt; câu trả lời khác đã quan sát thấy rằng C# không.

Cách xung quanh việc này là thực hiện lập trình meta từ bên ngoài ngôn ngữ, sử dụng program transformation tools. Các công cụ như vậy có thể phân tích cú pháp mã nguồn, và thực hiện các phép biến đổi tùy ý trên nó (đó là những gì metaprogramming làm anyway) và sau đó nhổ ra chương trình sửa đổi.

Nếu bạn có một hệ thống chuyển đổi chương trình mục đích chung, có thể phân tích ngôn ngữ tùy ý, bạn có thể thực hiện lập trình meta trên/với bất kỳ ngôn ngữ nào bạn muốn. Xem DMS Software Reengineering Toolkit của chúng tôi cho một công cụ như vậy, có các giao diện người dùng mạnh mẽ cho C, C++, Java, C#, COBOL, PHP và một số ngôn ngữ lập trình khác và đã được sử dụng để lập trình meta trên tất cả các công cụ này.D2 thành công vì nó cung cấp phương pháp thường xuyên và cơ sở hạ tầng hỗ trợ để truy cập hoàn toàn vào cấu trúc chương trình như AST, và trong hầu hết các trường hợp dữ liệu bổ sung như bảng biểu tượng, thông tin kiểu, kiểm soát và phân tích luồng dữ liệu. thao tác chương trình.

EDIT (để trả lời nhận xét): Người dùng có thể áp dụng DMS để triển khai nhiệm vụ của OP trên C#.

+2

-1: Câu trả lời hay, nhưng nó không trả lời câu hỏi cụ thể này. –

+1

@Saunders: Trên thực tế nó có, nhưng bạn đã làm một số bài tập về nhà. Nếu bạn muốn thực hiện nhiệm vụ cụ thể của OP, bạn sẽ cần phải thực hiện các phép biến đổi chương trình liên tục và tập trung chúng vào các cuộc gọi đến hàm Fibonacci của bạn. Tôi lưu ý rằng bạn dinged câu trả lời của tôi, khi không ai trong số các câu trả lời giải quyết các câu hỏi cụ thể của OP hoặc. –

+1

cảm ơn, bạn đã chỉ cho tôi đúng hướng cho một cái gì đó Im làm việc trên! –

22

Metaprogramming có thể có trong .NET (xem trình biên dịch biên dịch, biểu thức thông thường, mã DOM, phản xạ, vv) nhưng C# là không có khả năng mẫu Lập trình meta vì nó không có rằng tính năng ngôn ngữ.

+1

+1 để trả lời mọi khía cạnh của câu hỏi một cách nhanh chóng và toàn diện. –

0

Không theo cách bạn đang hỏi, nhưng bạn có thể sử dụng một số thủ thuật cũ C++ để tạo ra các lớp học có những đặc điểm được quy định tĩnh:

abstract class Integer 
{ 
    public abstract int Get { get; } 
} 

public class One : Integer { public override int Get { return 1; } } } 
public class Two : Integer { public override int Get { return 2; } } } 
public class Three : Integer { public override int Get { return 3; } } } 

public class FixedStorage<T, N> where N : Integer, new() 
{ 
    T[] storage; 
    public FixedStorage() 
    { 
     storage = new T[new N().Get]; 
    } 
    public T Get(int i) 
    { 
     return storage[i]; 
    } 
} 

Sử dụng này, bạn có thể định nghĩa các lớp học không gian:

public class Vector3 : FixedStorage<float, Three> {} 
public class Vector2 : FixedStorage<float, Two> {} 
public class GridCell : FixedStorage<int, Two> {} 

Tôi sử dụng kỹ thuật này trong thư viện có nhiều lớp con, nơi thêm thành viên dữ liệu mới yêu cầu nhiều bản mẫu.

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