2009-07-08 18 views
9

Mam klasy, która obecnie ma kilka metod, które biorą parametry liczb całkowitych. Te liczby całkowite są odwzorowywane na operacje, które może wykonywać aplikacja. Chciałbym uczynić klasą rodzajową, aby konsumenci klasy mogli podać typ wyliczeniowy, który mają ze wszystkimi operacjami w nim zawartymi, wtedy metody przyjmą parametry tego typu wyliczeniowego. Jednak chcę, aby nie byli w stanie określić typu ogólnego w ogóle i domyślnie powrócić do liczb całkowitych bez zmiany składni z obecnego sposobu. czy to możliwe?Jak podać typ domyślny dla generycznych?

+0

nie jest @ Vilx- rozwiązanie dobre podejście i lepszą odpowiedź? –

Odpowiedz

4

Nie można tego zrobić w definicji klasy:

var foo = new MyGenericClass(); // defaults to integer... this doesn't work 
var bar = new MyGenericClass<MyEnum>(); // T is a MyEnum 

Jeśli naprawdę cenimy implicitness domyślnego typu int samopoczucia, trzeba to zrobić ze statycznym fabryce metoda, chociaż nie widzę jej wartości.

public class MyGenericClass<T> 
{ 
    public static MyGenericClass<T> Create() 
    { 
     return new MyGenericClass<T>(); 
    } 
    public static MyGenericClass<int> CreateDefault() 
    { 
     return new MyGenericClass<int>(); 
    } 
} 

Zobacz poniżej, jak naprawdę nie korzystasz z powyższych.

var foo = MyGenericClass<MyEnum>.Create(); 
var bar1 = MyGenericClass.CreateDefault(); // doesn't work 
var bar2 = MyGenericClass<int>.CreateDefault(); // works, but what's the point 

Jeśli chcesz wziąć go jeszcze dalej, można utworzyć statyczną klasy fabrycznej, że rozwiąże to, ale to jeszcze bardziej absurdalne rozwiązanie jeśli robisz to dla żadnego innego powodu niż dostarczenie domyślne wpisz:

public static class MyGenericClassFactory 
{ 
    public static MyGenericClass<T> Create<T>() 
    { 
     return new MyGenericClass<T>(); 
    } 
    public static MyGenericClass<int> Create() 
    { 
     return new MyGenericClass<int>(); 
    } 
} 

var foo = MyGenericClassFactory.Create(); // now we have an int definition 
var bar = MyGenericClassFactory.Create<MyEnum>(); 
+0

tak, nie chcę wprowadzać tej złożoności, domyślnie nie jest to niezwykle ważne, byłoby po prostu miłe. Nie wiem, jak to zrobić, ale najpierw chciałem się upewnić, że wszyscy z was to zrobią.Dziękuję za odpowiedź –

1

Kompilator można wywnioskować argumentów typu na metod większość czasu w zależności od typu argumentów przekazany:

public void DoSomething<T>(T test) { 
} 

można nazwać z

DoSomething(4);     // = DoSomething<int>(4); 
DoSomething(MyEnum.SomeValue); // = DoSomething<MyEnum>(MyEnum.SomeValue); 

Nawiasem mówiąc, możesz mieć nietypowe przeciążenia metody ogólnej.

+0

Poszukuję klasy, która będzie w pewnym sensie "opcjonalnie ogólna". Nie sądzę, że jest to możliwe, więc będę musiał zrobić ogólne metody z nietypowymi przeciążeniami ... Szukałem tego "SecurityContext sec = new SecurityContext();" (który utworzyłby go przy użyciu liczb całkowitych dla parametrów, a następnie "SecurityContext sec = new SecurityContext ();" który utworzyłby go przy użyciu MyOperations dla parametrów –

2

Zachowaj oryginalną wersję (wersja nietypowa) i utwórz jej ogólną wersję.

Następnie wywołaj wersję ogólną ze swojej wersji generycznej.

void Main() 
{ 
DoSomething(2); 
DoSomething(EnumValue); 

} 

public void DoSomething(int test) { 
DoSomething<int>(test); 
} 

// Define other methods and classes here 
public void DoSomething<T>(T test) { 
Console.WriteLine(test); 
} 
+0

Ogólny typ parametru będzie taki sam dla wszystkich metod, więc Chciałbym to na poziomie klasy. Wiem, że mógłbym stworzyć wersję generyczną, a następnie odziedziczyć po niej wersję int, ale miałem nadzieję, że wszystko to w jednym ... ale nie znałem żadnego sposobu Myślę, że nie jest to możliwe w tak prosty sposób, jak miałem nadzieję, –

12

A więc ... czemu nie użyć prostego dziedziczenia? Jak:

class MyGenericClass<T> 
{ 
} 

class MyGenericClass : MyGenericClass<int> 
{ 
} 

ten sposób można napisać w obie strony:

var X = new MyGenericClass<string>(); 
var Y = new MyGenericClass(); // Is now MyGenericClass<int> 
Powiązane problemy