2011-01-08 21 views
16

Czy jest coś podobnego do tego szablonu C++?C# generic ze stałą

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

Chcę, aby każde wystąpienie B < 1>, B < 2> etc (np krotki) inny typ.

Odpowiedz

18

Krótka odpowiedź to nr.

To nie pasuje do sposobu generowania C#, zgodnie z szablonami C++.

Generics .net nie są funkcjami językowymi, są funkcją uruchomieniową. Środowisko wykonawcze wie, jak utworzyć generics ze specjalnego ogólnego kodu bajtowego, który jest raczej ograniczony w porównaniu do tego, co można opisać w szablonach C++.

Porównaj to z szablonami C++, które w zasadzie tworzą instancję klasy AST za pomocą typów podstawionych. Byłoby możliwe dodanie do środowiska wykonawczego instancji opartej na AST, ale z pewnością byłby on znacznie bardziej złożony niż obecne generyczne.

Bez funkcji, takich jak tablice wartości (które istnieją tylko w niebezpiecznym kodzie), rekurencyjne tworzenie szablonów lub specjalizacja szablonów przy użyciu takich parametrów również nie byłoby zbyt użyteczne.

+1

W środowisku wykonawczym (JIT) .Net tworzy instancję. Tworzenie jest zasadniczo duplikacją z modyfikacjami. Nie sprzeciwiałbym się takiemu AST jak MSIL. Różne reprezentacje podobnych pojęć. –

12

C# nie obsługuje nietypowych parametrów ogólnych, takich jak C++.

C# generics są znacznie prostsze i mniej zdolne niż szablony C++. MSDN ma zwięzłą listę Differences Between C++ Templates and C# Generics.

+1

Jednakże dodatkowe informacje mogą być " zakodowane "w typy (według definicji kontraktu lub w inny sposób), można je łatwo zobaczyć za pomocą ustalonego zestawu dyskretnych typów (np.' Vn: V, gdzie Vn.Value = n dla wszystkich Vn'), ale są również [cyfry kościelne] (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) - nie polecam * ani podejścia * tutaj :-) –

+1

Niepoprawna odpowiedź, ale byłoby miło, gdyby zawierała link do generycznych C# i/lub mówiła o deklaracja ogólna/"tworzenie instancji" a tworzenie szablonu. –

+3

@pst: Sure; możesz kodować informacje do typów. Możesz także całkowicie uniknąć generycznych rodzajów i napisać wiele nienazwanych klas. W każdym przypadku; Dodałem link do artykułu MSDN wyliczający główne różnice między szablonami i rodzajami. –

5

C# generics są wyspecjalizowane w czasie wykonywania, podczas gdy szablony C++ są przetwarzane podczas kompilacji, aby stworzyć całkowicie nowy typ. Biorąc pod uwagę to, środowisko wykonawcze po prostu nie ma funkcji do przetwarzania parametrów nietypowych (nie jest to tylko kwestia C#).

8

obejście tego ograniczenia jest zdefiniowanie klasy, która sama naraża wartość literalną jesteś zainteresowany. Na przykład:

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) ... 
    } 
} 

Zastosowanie:

var myObject = new MyTemplateClass<LiteralInt10>();