Question

I'm working in a C# web service with a generic static class that takes a type. I was wondering why this does not compile:

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

It gives this error:

The type or namespace name 'type1' could not be found (are you missing a using directive or an assembly reference?)

And ReSharper, when I hover over type1 in that second line of code, says "Type or namespace name expected". Well, type1 is a type! It's a variable of type Type! It also doesn't work if I do:

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

I was hoping to assign my types to a couple of different Type variables and just use those in testing the different generic static classes, instead of typing out MySnazzyType each time. Any ideas, or am I stuck with doing:

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

Edit: to clarify, MySnazzyType is not a generic class, nor does it inherit from a generic class. The only generic class here is ConnectionPool_Accessor.

Thanks to Pavel's comment "Essentially, your problem is that C# is a statically typed language", I now know that Ruby has spoiled me. ;)

Was it helpful?

Solution

First of all, ReSharper is actually correct. It isn't a type, it's a variable. Granted, it's a variable that is holding the reflection object that corresponds to a type, but that isn't enough.

Between the <...> brackets, you have to write the name of a type, not the name of any other identifier.

You can construct generic objects through reflection, however, and access their properties, even static ones, so you should be able to rewrite the code to do that, however, have you looked at NUnit 2.5?

From the latest release notes, it appears that unit test classes can now be generic, and you can specify with an attribute on the test class which types to test it with.

This would allow you to write something like this (note, I have not tested this, I only looked up the names of the new attributes in the documentation):

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

OTHER TIPS

Generic types are evaluated at compile time, not in runtime. Since it cannot be determined at runtime time what type1 will be, this construct is not allowed.

This is actually what Resharper says: type1 is not a Type, it's a variable of the type Type, (just as it could be an object of the type String).

The TestFixture attribute should set you up, but just for the heck of it: if you wanted to do all this at runtime, you could do so using reflection.

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

You could then proceed to do whatever you want using reflection on poolType. Of course, that will be a major pain in the butt unless you use C# 4.0 dynamic typing.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top