Weisen Sie der Variablen einen Typ und verwenden Sie die Variable mit der generischen statischen Klasse

StackOverflow https://stackoverflow.com/questions/1174635

Frage

Ich arbeite in einem C# Webdienst mit einer generischen statischen Klasse, die einen Typ annimmt. Ich habe mich gefragt, warum das nicht kompiliert wird:

Type type1 = typeof(MySnazzyType);
Assert.AreEqual(0, ConnectionPool_Accessor<type1>._pool.Count);

Es gibt diesen Fehler:

Der Typ- oder Namespace -Name 'Typ1' konnte nicht gefunden werden (fehlt Ihnen eine verwendete Richtlinie oder eine Montagereferenz?)

Und Umresharper, wenn ich übersehe type1 In dieser zweiten Codezeile heißt es "Typ- oder Namespace -Name erwartet". Brunnen, type1 ist eine Art! Es ist eine Variable des Typs Type! Es funktioniert auch nicht, wenn ich es tue:

Type type1 = typeof(MySnazzyType);
Assert.AreEqual(0, ConnectionPool_Accessor<typeof(type1)>._pool.Count);

Ich hatte gehofft, meine Typen ein paar verschiedenen zuzuweisen Type Variablen und verwenden Sie diejenigen, um die verschiedenen generischen statischen Klassen zu testen, anstatt herauszugeben MySnazzyType jedes Mal. Alle Ideen oder stehe ich bei:

Assert.AreEqual(0, ConnectionPool_Accessor<MySnazzyType>._pool.Count);

Bearbeiten: um klarzustellen, MySnazzyType ist nicht Eine generische Klasse, noch erbt sie von einer generischen Klasse. Die einzige generische Klasse hier ist ConnectionPool_Accessor.

Dank Pavels Kommentar "Im Wesentlichen ist Ihr Problem, dass C# eine statisch getippte Sprache ist", weiß ich jetzt, dass Ruby mich verwöhnt hat. ;))

War es hilfreich?

Lösung

Zunächst ist Resharper tatsächlich korrekt. Es ist nicht ein Typ, es ist ein Variable. Zugegeben, es ist eine Variable, die das Reflexionsobjekt hält, das einem Typ entspricht, aber das ist nicht genug.

Zwischen den <...> Klammern müssen Sie den Namen eines Typs schreiben, nicht den Namen eines anderen Kennung.

Sie können jedoch generische Objekte durch Reflexion konstruieren und auf ihre Eigenschaften zugreifen, sogar statische.

Aus den neuesten Versionshinweisen scheint es, dass Unit -Testklassen jetzt generisch sein können, und Sie können mit einem Attribut in der Testklasse angeben, mit der es testen soll.

Auf diese Weise können Sie so etwas schreiben (beachten Sie, ich habe dies nicht getestet, ich habe nur die Namen der neuen Attribute in der Dokumentation nachgeschlagen):

[TestFixture(typeof(MySnazzyType))]
[TestFixture(typeof(MyOtherSnazzyType))]
public class Tests<T>
{
    [Test]
    public void PoolCount_IsZero()
    {
        Assert.AreEqual(0, ConnectionPool_Accessor<T>._pool.Count);
    }
}

Andere Tipps

Generische Typen werden bei bewertet Zeit kompilieren, nicht in Laufzeit. Da es nicht zur Laufzeit festgelegt werden kann was was type1 wird sein, dieses Konstrukt ist nicht erlaubt.

Dies ist tatsächlich das, was Resharper sagt: type1 ist kein Typ, es ist eine Variable des Typs Type, (so wie es ein Objekt des Typs sein könnte String).

Das TestFixture Das Attribut sollte Sie einrichten, aber nur zum Teufel: Wenn Sie das alles zur Laufzeit tun wollten, können Sie dies mit Reflexion tun.

Type poolType = typeof(ConnectionPool_Accessor<>);
Type snazzyType = typeof(MySnazzyType); // Or however you want to get the appropriate Type
poolType.MakeGenericType(snazzyType);

Sie könnten dann fortfahren, was Sie mit Reflection verwenden möchten poolType. Das ist natürlich ein großer Schmerz im Hintern, es sei denn, Sie verwenden C# 4.0 Dynamisches Tippen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top