2012-10-26 3 views
7

Ich habe eine Klasse dieser Art verzichten:Was ist, wenn T in Generics ungültig ist? Wie spitze Klammern

class A<TResult> 
{ 
    public TResult foo(); 
} 

Aber manchmal brauche ich diese Klasse als nicht generische Klasse zu verwenden, dh die Art TResultvoid ist.
Ich kann die Klasse in der folgenden Art und Weise instanziiert:

var a = new A<void>(); 

Auch würde ich eher nicht den Typ angeben, die spitzen Klammern Weglassen:

var a = new A(); 

Ich will nicht wieder- schreibe die ganze Klasse, weil sie das Gleiche macht.

+1

Kannst du 'Objekt' nicht einfach verwenden? – Davio

+0

@Davio ja, aber es ist schrecklich ... – Nick

+3

In diesem Fall müssen Sie eine separate Klasse "A" ohne die Einschränkung erstellen. Aber wie sieht die Klassenimplementierung ohne T aus? Sie haben eine 'T foo()' Methode darauf. Was sollte T im Fall von nichtig sein? – nawfal

Antwort

8

Die void ist kein echter Typ in C#, auch gibt es eine entsprechende System.Void Struktur in FCL. Ich fürchte, Sie brauchen eine nicht-generische Version hier wie folgt aus:

class A 
{ 
    //non generic implementation 
} 

class A<T> : A 
{ 
    //generic implementation 
} 

Sie in FCL es sehen können System.Action/System.Action<T>, statt System.Action<void> sowie Task statt Task<void> sind.

EDIT Von CLI specification(ECMA-335):

Die folgenden Arten von Typ können nicht als Argument in instantiations verwendet werden (von generischen Typen oder Methoden):

ByRef Typen (zB System.Generic. Collection.List`1 < Zeichenfolge &> ist ungültig)

Werttypen, die Felder enthalten, die in t zeigen können er CIL Auswertungsstapel (zB Liste < System.RuntimeArgumentHandle>)

void (zB Liste < System.Void> ist ungültig)

4

Wie ich in Kommentar geschrieben Sie können es gut aussehen durch Erben von generischer Klasse:

class A:A<object> 
{ 
} 

Dies zeigt deutlich die allgemeinen Parameter versteckt aber, dass ich dies in meiner Erfahrung bewusst sein, dies ist der falsche Weg Klassen erbt und jedes Mal habe ich es bereute, während meine Klasse komplexer bekam.

+0

stattdessen kann ich eine Klasse mit Hunderten von Zeilen Code wiederverwenden und nur ein paar Dutzend mit diesem Trick +1 hinzufügen – Nick

1

void ist einfach kein Typ in C#, Sie können es also nicht als Typparameter verwenden. Nichtsdestotrotz gibt es Zeiten, in denen man eine Funktionalität so haben möchte, als wäre sie eine.

In dieser Art von Fall können Sie einen einfachen Ersatztyp verwenden, höchstwahrscheinlich einen sehr kleinen, wie zum Beispiel System.Reactive.Unit in Reactive Extensions.

Verwandte Themen