2009-07-23 2 views
4

Я работаю в веб-службе C# с общим статическим классом, который принимает тип. Мне было интересно, почему это не компилируется:присваивать тип переменной, использовать переменную с общим статическим классом

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

Это дает эту ошибку:

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

И ReSharper, когда я наведите курсор мыши на type1 в этой второй строке кода, говорит «Тип или пространство имен Предположительное имя ». Хорошо, type1is a type! Это переменная типа Type! Он также не работает, если я делаю:

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

Я надеялся назначить свои типы в нескольких различных Type переменных и использовать только те, в тестировании различных генерических статические классы, вместо того, чтобы печатать из MySnazzyType каждый раз , Любые идеи, или я застрял с делать:

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

Edit: уточнить, MySnazzyType является не общий класс, и не наследуют от общего класса. Единственный общий класс здесь - ConnectionPool_Accessor.

Благодаря замечанию Павла «По сути, ваша проблема в том, что C# является статически типизированным языком», теперь я знаю, что Ruby испортил мне. ;)

+0

s/испортил меня/научил меня плохим манерам/;-) – Thorarin

ответ

3

Прежде всего, ReSharper на самом деле правильный. Это не тип, это переменная . Конечно, это переменная, которая удерживает объект отражения, соответствующий типу, но этого недостаточно.

Между скобками < ...> вы должны написать имя типа, а не имя другого идентификатора.

Однако вы можете создавать общие объекты посредством отражения и получать доступ к их свойствам, даже статическим, чтобы вы могли переписать код, чтобы сделать это, однако, вы посмотрели на NUnit 2.5?

Из последних примечаний к выпуску стало очевидно, что классы модульных тестов теперь могут быть общими, и вы можете указать атрибут класса тестирования, который должен тестировать его.

Это позволит вам написать что-то вроде этого (примечание, я не проверял это, я только посмотрел имена новых атрибутов в документации):

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

Общие типы оцениваются в время компиляции, а не в время выполнения. Поскольку во время выполнения не может быть определено, что такое type1, эта конструкция не допускается.

Это на самом деле то, что говорит Resharper: type1 не тип, это переменная типа Type, (так же, как это может быть объектом типа String).

+0

Э-э, вы обменялись тем, что вы хотели сказать? Возможно, «общие типы оцениваются в _runtime_, а не в _compile time_». –

+0

Кроме того, почему он не может определить в компиляторе тип 'type1', поскольку он выписан как' typeof (MySnazzyType) '? –

+1

Нет, он написал это правильно. Типичным типом в вашем случае является 'ConnectionPool_Accessor <>', и он действительно разрешен во время компиляции. И в этот момент нет способа сказать, какой тип будет 'type1' решать. По сути, ваша проблема в том, что C# является статически типизированным языком. –

1

Атрибут TestFixture должен поставить вас но просто для этого: если вы хотите сделать все это во время выполнения, вы можете сделать это, используя отражение.

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

Затем можно продолжить делать то, что вы хотите с помощью отражения на poolType. Конечно, это будет серьезной болью в прикладе, если вы не используете динамическую типизацию C# 4.0.

Смежные вопросы