Присвоить тип переменной, используйте переменную с общим статическим классом
-
19-09-2019 - |
Вопрос
Я работаю в веб -службе C# с общим статическим классом, который принимает тип. Мне было интересно, почему это не компилируется:
Type type1 = typeof(MySnazzyType);
Assert.AreEqual(0, ConnectionPool_Accessor<type1>._pool.Count);
Это дает эту ошибку:
Тип или имя пространства имен «Тип1» не может быть найдено (вам не хватает директивы или ссылки на сборку?)
И Resharper, когда я нахожусь type1
В этой второй строке кода говорится: «Тип или имя пространства имен ожидается». Что ж, type1
является тип! Это переменная типа Type
! Это также не работает, если я сделаю:
Type type1 = typeof(MySnazzyType);
Assert.AreEqual(0, ConnectionPool_Accessor<typeof(type1)>._pool.Count);
Я надеялся назначить свои типы несколько разных Type
переменные и просто используйте те, кто тестирует различные общие статические классы, вместо печати MySnazzyType
каждый раз. Любые идеи, или я застрял:
Assert.AreEqual(0, ConnectionPool_Accessor<MySnazzyType>._pool.Count);
Редактировать: чтобы уточнить, MySnazzyType
является нет общий класс, и он не наследует от общего класса. Единственный общий класс здесь ConnectionPool_Accessor
.
Благодаря комментарию Павела «по сути, ваша проблема в том, что C# - статически напечатанный язык», я теперь знаю, что Руби испортила меня. ;)
Решение
Прежде всего, Решарпер на самом деле прав. Это не тип, это переменная. Анкет Конечно, это переменная, которая удерживает объект отражения, который соответствует типу, но этого недостаточно.
Между кронштейнами <...> вы должны написать имя типа, а не имя любого другого идентификатора.
Однако вы можете построить общие объекты посредством отражения и получить доступ к их свойствам, даже статическим, поэтому вы должны быть в состоянии переписать код, чтобы сделать это, однако, смотрели ли вы на 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);
}
}
Другие советы
Общие типы оцениваются на Время компиляции, не в время выполнения. Анкет Поскольку это не может быть определено во время выполнения, что type1
будет, эта конструкция не допускается.
Это на самом деле то, что говорит Решарпер: type1
не является типом, это переменная типа Type
, (так же, как это может быть объектом типа String
).
А 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.