Доступ к статическому вложенному классу универсального типа

У меня есть класс:

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

Как правильно получить доступ к вложенным статическим и нестатическим классам в с #?

private static void Work<T>() where T: MyClass не знаю, может ли это сработать тоже :)
CodeNotFound 14.06.2018 15:45

@CodeNotFound У меня есть несколько классов, в каждом из которых есть MyNestedClass. вариант использования: EventProvider и Tasks - статический внутренний класс.

Ashish Negi 14.06.2018 15:46

Тогда я прочитаю это.

CodeNotFound 14.06.2018 15:47

«У меня есть несколько классов, в каждом из которых есть MyNestedClass». Ты? Как компилятор должен это знать?

mm8 14.06.2018 15:50

Почему вы вообще используете здесь вложенные классы? Мне это кажется ужасным запахом кода.

DavidG 14.06.2018 15:51

Статические типы нельзя использовать в качестве универсальных аргументов. Вы не можете сделать List<MyClass.MyNestedClass> ... Даже если бы MyNestedClass не был вложенным, это ничего бы не изменило.

xanatos 14.06.2018 15:52
EventSource в C# требует наличия вложенного класса Task с несколькими EventTask внутри него. msdn.microsoft.com/en-us/library/… Аналогично EventProvider в моем случае.
Ashish Negi 14.06.2018 15:53

Если я удалю static из класса, поможет ли T.MyNestedClass?

Ashish Negi 14.06.2018 15:55

Имейте в виду, что где бы вы ни идентифицировали тип по имени в своем коде, компилятор должен идентифицировать тот тип, о котором ты говоришь и помещать токен в IL, который идентифицирует конкретный тип - который будет либо конкретным типом, либо параметром универсального типа. Когда вы говорите что-то вроде A.B.C, то выдаваемый токен типа предназначен для C. Это нет "сначала найдите тип / пространство имен A, затем в отдельности найдет в нем B, а затем найдет C в что.

Damien_The_Unbeliever 14.06.2018 15:55

@ mm8 Я придумал способ принудительного исполнения по constraints.

Ashish Negi 14.06.2018 15:55

Эта ссылка MSDN - не лучший код. Вложенным типом вполне может быть, например, private, но нет никакого преимущества, чтобы он был вложенным классом.

DavidG 14.06.2018 15:56

@DavidG Он не может быть приватным, поскольку он используется EventSource для генерации динамических манифестов.

Ashish Negi 14.06.2018 15:57

И я полностью согласен, что это не лучший код, но отсутствие вложенности для меня не вариант.

Ashish Negi 14.06.2018 15:58

@AshishNegi: вы не можете использовать ограничения, чтобы заставить тип иметь вложенный тип ...

mm8 14.06.2018 15:58

Generic здесь бессмысленен. Он ничего не делает, просто замените T на MyClass

Liam 14.06.2018 16:13
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
4
15
165
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Тип T не имеет вложенного типа с именем MyNestedClass, если вы не укажете, что T фактически является MyClass. Затем вы можете использовать метод GetNestedTypes() для получения вложенного типа:

private static void Work<T>() where T : MyClass
{
    Type myType = typeof(T).GetNestedTypes().FirstOrDefault();
    //...
}

Существует метод GetNestedType, который также принимает имя типа string.

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

GetNestedType ("Задачи") лучше, если мне нужно использовать отражение.

Ashish Negi 14.06.2018 15:49

Если T : MyClass, то какой вообще смысл в дженерике? Вы могли бы просто использовать MyClass вместо T?

Liam 14.06.2018 16:12

@Liam: Да, если MyClass не является базовым классом или интерфейсом.

mm8 14.06.2018 16:14

@Liam у меня есть несколько классов с одним и тем же вложенным классом. Пример использования в реальном мире: несколько вложенных классов EventSource и Tasks.

Ashish Negi 14.06.2018 16:19
"вы не можете использовать ограничения, чтобы заставить определенный тип иметь вложенный тип ..." +1
Glenn Slayden 22.08.2020 05:29

Да, и между прочим (поскольку он не упоминался в другом месте на этой странице), с точки зрения вложенного (или «закрытого») типа, его содержащий («внешний») тип может быть обнаружен через его свойство Type.DeclaringType. ..

Glenn Slayden 18.10.2020 21:51

Другие вопросы по теме