У меня есть класс:
class MyClass
{
public static class MyNestedClass
{
public const int M1 = 1;
public const int M2 = 2;
}
}
class MyClass2
{
public static class MyNestedClass
{
public const int M1 = 1;
public const int M2 = 2;
}
}
и общая функция:
private static void Work<T>()
{
Type myType = typeof(T.MyNestedClass);
myType.GetFields().Select(....);
// .. use T here as well..
}
Получаю ошибку: error CS0704: Cannot do member lookup in 'T' because it is a type parameter.
Поскольку MyNestedClass является статическим классом, когда я пытаюсь передать его как другой аргумент универсального типа, как:
private static void Work<T, S>()
{
Type myType = typeof(S);
myType.GetFields().Select(....);
// .. use T here as well..
}
Звонок через,
Work<MyClass, MyClass.MyNestedClass>();
дает мне ошибку: static types cannot be used as type arguments
Как правильно получить доступ к вложенным статическим и нестатическим классам в с #?
@CodeNotFound У меня есть несколько классов, в каждом из которых есть MyNestedClass. вариант использования: EventProvider и Tasks - статический внутренний класс.
Тогда я прочитаю это.
«У меня есть несколько классов, в каждом из которых есть MyNestedClass». Ты? Как компилятор должен это знать?
Почему вы вообще используете здесь вложенные классы? Мне это кажется ужасным запахом кода.
Статические типы нельзя использовать в качестве универсальных аргументов. Вы не можете сделать List<MyClass.MyNestedClass> ... Даже если бы MyNestedClass не был вложенным, это ничего бы не изменило.
EventSource в C# требует наличия вложенного класса Task с несколькими EventTask внутри него. msdn.microsoft.com/en-us/library/… Аналогично EventProvider в моем случае.
Если я удалю static из класса, поможет ли T.MyNestedClass?
Имейте в виду, что где бы вы ни идентифицировали тип по имени в своем коде, компилятор должен идентифицировать тот тип, о котором ты говоришь и помещать токен в IL, который идентифицирует конкретный тип - который будет либо конкретным типом, либо параметром универсального типа. Когда вы говорите что-то вроде A.B.C, то выдаваемый токен типа предназначен для C. Это нет "сначала найдите тип / пространство имен A, затем в отдельности найдет в нем B, а затем найдет C в что.
@ mm8 Я придумал способ принудительного исполнения по constraints.
Эта ссылка MSDN - не лучший код. Вложенным типом вполне может быть, например, private, но нет никакого преимущества, чтобы он был вложенным классом.
@DavidG Он не может быть приватным, поскольку он используется EventSource для генерации динамических манифестов.
И я полностью согласен, что это не лучший код, но отсутствие вложенности для меня не вариант.
@AshishNegi: вы не можете использовать ограничения, чтобы заставить тип иметь вложенный тип ...
Generic здесь бессмысленен. Он ничего не делает, просто замените T на MyClass





Тип T не имеет вложенного типа с именем MyNestedClass, если вы не укажете, что T фактически является MyClass. Затем вы можете использовать метод GetNestedTypes() для получения вложенного типа:
private static void Work<T>() where T : MyClass
{
Type myType = typeof(T).GetNestedTypes().FirstOrDefault();
//...
}
Существует метод GetNestedType, который также принимает имя типа string.
Но вы не можете использовать ограничения, чтобы заставить конкретный тип иметь вложенный тип.
GetNestedType ("Задачи") лучше, если мне нужно использовать отражение.
Если T : MyClass, то какой вообще смысл в дженерике? Вы могли бы просто использовать MyClass вместо T?
@Liam: Да, если MyClass не является базовым классом или интерфейсом.
@Liam у меня есть несколько классов с одним и тем же вложенным классом. Пример использования в реальном мире: несколько вложенных классов EventSource и Tasks.
Да, и между прочим (поскольку он не упоминался в другом месте на этой странице), с точки зрения вложенного (или «закрытого») типа, его содержащий («внешний») тип может быть обнаружен через его свойство Type.DeclaringType. ..
private static void Work<T>() where T: MyClassне знаю, может ли это сработать тоже :)