:: Не фоксом единым
Вложенные класы
S-type
Автор

Сообщений: 2969
Дата регистрации: 24.04.2004
Есть такой код:

public static class MyClass
{
public class MyNestedClass1
{
public static string MyFunc()
{
return typeof(MyNestedClass1).Name;
}
}
public class MyNestedClass2
{
public static string MyFunc()
{
return typeof(MyNestedClass2).Name;
}
}
}
static class Program
{
static void Main(string[] args)
{
Console.WriteLine(MyClass.MyNestedClass1.MyFunc()); // MyNestedClass1
Console.WriteLine(MyClass.MyNestedClass2.MyFunc()); // MyNestedClass2
Console.ReadLine();
}
}

Реально ли вынести MyFunc() в отдельного предка, примерно так:

public static class MyClass
{
public class MyNestedClass
{
public static string MyFunc()
{
return что_то;
}
}
public class MyNestedClass1: MyNestedClass
{
}
public class MyNestedClass2 : MyNestedClass
{
}
}

Что бы при этом выводился тот же результат?
Ratings: 0 negative/0 positive
Re: Вложенные класы
S-type
Автор

Сообщений: 2969
Дата регистрации: 24.04.2004
По сути, это сводится к вопросу - как в методе MyFunc получить имя реального (а не базового) класса .

public class MyNestedClass
{
public static string MyFunc()
{
return typeof(MyNestedClass).Name; // MyNestedClass
}
}



Исправлено 6 раз(а). Последнее : S-type, 16.10.18 20:31
Ratings: 0 negative/0 positive
Re: Вложенные класы
Igor Korolyov

Сообщений: 34580
Дата регистрации: 28.05.2002
Имя чего ты хочешь получить - вот ключевой вопрос...

typeof(неважно_что) по сути является константой и "вычисляется" во время компиляции.

Тип конкретного объекта можно получить через его метод GetType() (этот метод определён в типе System.Object - базовом для любых других типов C# и потому применим к любому объекту).

Поскольку статические методы не связаны с объектами, из них в принципе бессмысленно получать в рантайме "метод какого объекта я есть" - т.к. статический метод это метод того типа в котором он определён - ты никак не сможешь его вызвать к примеру через MyNestedClass1.MyFunc() - только и всегда как MyNestedClass.MyFunc(). Конечно в этот метод можно передать параметром ссылку на объект, и уже смотреть тип этого объекта - и это тривиально. Можно ещё смотреть стек вызовов и по нему определять из какого метода был вызов этого статика (а значит и тип объекта с этим методом связанный можно получить) - не передавая никаких параметров в метод-детектор - и это очень черезжопошно.

Вообще не понимаю к чему тут вложенные типы, если то о чём ты спрашиваешь никак не зависит от этого самого "вложения".

Манипулировать типами вне задач рефлексии практически никогда не требуется - собственно говоря именно ради рефлексии и существует тип System.Type, получаемый либо в рантайме для объекта, либо во время компиляции если нам нужен конкретный, статически определённый тип (просто написать "имя_типа" в качестве параметра, или в качестве объекта чей метод GetMethod() мы хотим вызвать конечно же нельзя, это синтаксис вызова статичских методов данного типа - а вот typeof(имя_типа) - как раз можно - это даёт доступ к экземпляру System.Type связанному с нашим "имя_типа").

Лучше бы сказал что за задачу ты пытаешься решить таким образом, ибо есть большая доля уверенности что ты идёшь неверным путём...


------------------
WBR, Igor
Ratings: 0 negative/0 positive
Re: Вложенные класы
S-type
Автор

Сообщений: 2969
Дата регистрации: 24.04.2004
Главный вопрос "Реально ли". Понятно, что если "это фантастика", то придётся переделывать всю структуру (например - вместо вложенных классов создать свойства).

Классы MyNestedClass1 это ведь не статические классы? Если бы они были статические, их нельзя было бы отнаследовать от MyNestedClass. Так?

Но, экземпляра переменной нет. Потому, GetMethod() не задействовать.



Исправлено 1 раз(а). Последнее : S-type, 17.10.18 11:45
Ratings: 0 negative/0 positive
Re: Вложенные класы
Igor Korolyov

Сообщений: 34580
Дата регистрации: 28.05.2002
Ещё раз - ЧТО ТЫ ХОЧЕШЬ ПОЛУЧИТЬ.
Не можешь словами - код тестового примера давай и в точке затруднения укажи что должно быть.

Пока я не вижу вообще никакого здравого смысла в вопросе. Если нет экземпляров, то тип ЧЕГО ты собираешься получать? Статический метод привязан всегда к тому типу в котором прописан - и никакие "наследники" (статический метод может быть и в обычном, нестатическом классе) не изменять сути - того что это метод самого типа, а не объекта - он "сбоку" от объекта находится всегда.
Можно вообще считать (в определённой мере, конечно) что статический метод это "глобальная процедура/функция" - нечто НЕ связанное с объектами. Да, конечно, видимость членов, доступ без указания имени типа изнутри инстанс-методов и т.п. - это всё есть, но всё это не важно до тех пор пока ты не поймёшь разницу между типом и объектом/экземпляром.


------------------
WBR, Igor
Ratings: 0 negative/0 positive
Re: Вложенные класы
S-type
Автор

Сообщений: 2969
Дата регистрации: 24.04.2004
Интересовал вопрос - теоретически, можно ли так сделать. Если можно, но только танцами через стек выполнения - даром не нужно, просто переделаю класс как нужно.

Спасибо за помощь.
Ratings: 0 negative/0 positive
Re: Вложенные класы
Аспид

Сообщений: 3475
Откуда: Москва
Дата регистрации: 01.04.2005
Мне кажется тут какая то путаница.
В рабочем ПО, классов нет, там есть объекты классов.
Это как жилье, есть проект, а есть дом.
Так вот, класс - это проект.

Потому, в рабочем ПО, можно говорить и вытаскивать инфу из объекта (в том числе о его классе)...

Или вопрос сформулирован как то не так.


------------------
Ratings: 0 negative/0 positive
Re: Вложенные класы
Igor Korolyov

Сообщений: 34580
Дата регистрации: 28.05.2002
Аспид
В рабочем ПО, классов нет, там есть объекты классов.
Есть и сами типы, и объекты [типов], и System.Type - который есть способ "косвенного" доступа к типам/объектам/метаинформации.
Статические члены классов самый яркий пример использования "типов" в ПО - без надобности в объектах (этих самых типов).

Аспид
Или вопрос сформулирован как то не так.
В том то и дело что вопрос не сформулирован никак - я лично совершенно не понял ЧТО нужно получить. Т.е. если взять "чёрный ящик" из этого самого статик типа и его вложенных типов, и некоторый статик метод MyFunc() - при том автор вопроса несколько "путается в показаниях" - должен быть это "идеологически" (т.е. то как оно видимо снаружи) один метод, или несколько разных. И взять некоторый внешний код который как-то манипулирует этим "чёрным ящиком" - то ЧТО должен делать этот внешний код, и что он должен получать в ответ.

Отвечая "в лоб" из двух статик методов невозможно сделать один который бы "работал так же". Т.к. во-первых вызывающий код всегда (явно или неявно) при вызове указывает конкретный тип, чей статик метод вызывается. Это для инстанс-методов можно указывая одно и тот же имя метода (и даже используя одну и ту же сигнатуру - т.е. список типов параметров) по сути обращаться к разным методам (переопределение aka override) - т.е. нечто в классе-наследнике заменяет "базовую реализацию".
Кроме того вызов инстанс метода всегда связан с некоторым объектом (опять же хоть явно, хоть неявно, т.е. подразумевая this), т.к. по синтаксису такой вызов делается через ссылка_на_объект.метод(). И для инстанс методов порой имеет смысл определять рантайм тип - т.е. что же за ссылка_на_объект была при его вызове - то ли это ссылка на объект типа classA, то ли на classB, а может и вовсе на baseClassOfAB.
Для статиков всё не так - вызов статика всегда идёт через имя_типа.метод() (опять же не важно явно или неявно) статик не получает неявного this - только то что явно параметрами передано. Ему вообще никакого объекта не требуется, чтобы можно было его вызвать. Статик невозможно переопределить. Потому сама задача определения какого-то непонятно какого типа (о чём я и толкую всё время - тип ЧЕГО хочется определить то?) в таком методе выглядит странной. Тип который содержит статик метод всегда очевиден на этапе компиляции - если вдруг зачем-то нужно получить средство для рефлексии, то именно typeof() тут и должен быть. Если зачем-то нужно узнавать тип объекта из метода которого был вызов данного статик метода - учитывая что таковой вызов вполне мог быть и из другого статик метода - например "классического" Program.Main, где тоже никаких "объектов", и тип будет неизменен со времени компиляции - ну да, надо через зад смотреть. Или же просто параметр в статике сделать, куда передавать ссылку на тот объект, тип которого должен зачем-то "знать" статик (но это часто говорит об изъяне в архитектуре)...
В общем пока мы так и не заслушали "начальника транспортного цеха", который бы рассказал ЧТО он хочет сделать, а не то КАК он пытался это делать

P.S. Вообще статики это очень опасная штука - наверное даже пострашнее глобальных переменных фокса - их то хоть можно удалить, или "заменить" Лучше уж реализовывать синглтон - хотя и он во многих случаях будет антипаттерном, т.е. тем что НЕ надо делать.


------------------
WBR, Igor




Исправлено 1 раз(а). Последнее : Igor Korolyov, 19.10.18 21:55
Ratings: 0 negative/0 positive
Re: Вложенные класы
_vit

Сообщений: 5173
Дата регистрации: 29.07.2002
Igor Korolyov
Аспид
В рабочем ПО, классов нет, там есть объекты классов.
Есть и сами типы, и объекты [типов], и System.Type - который есть способ "косвенного" доступа к типам/объектам/метаинформации.
Статические члены классов самый яркий пример использования "типов" в ПО - без надобности в объектах (этих самых типов).

Но по существу статические члены классов это все равно члены объектов только глобальных и создаются они неявно, в единственном экземпляре, автоматически
до первого использования, без явного указания new.
Ratings: 0 negative/0 positive
Re: Вложенные класы
Igor Korolyov

Сообщений: 34580
Дата регистрации: 28.05.2002
Терминологически это называется тип, а не объект. Тип в дотнете, конечно же, вполне себе "физически ощущаем" - т.е. это структура в памяти (точнее там весьма много структур - ключевые из которых это MethodTable и EEClass). Но я не думаю что ТС стоит сейчас углубляться в тонкости внутренней организации системы типов CLR, а то взрыв мозга и всё такое

Ну, к примеру, статические ПОЛЯ типов хранятся во внутренней структуре MethodTable, наряду со специальными указателями на методы типов - при том как инстанс методов, так и статических. Меня всегда коробит когда при описании статиков (как static классов, так и отдельных static членов класса) начинают нести чушь про то что "статические методы присутствуют в памяти только один раз, в отличие от инстанс методов". ЛЮБОЙ код присутствует в памяти один раз, разработчики такого рода систем не нестолько дебилы, чтобы зачем-то дублировать гарантированно неизменную сущность, т.е. код. Но ещё раз повторюсь - для прикладного разработчика на дотнете в эту часть лучше не влазить до тех пор пока "идеально" не будет пониматься спецификация языка - в частности ключевые отличия статических и нестатических членов типа.


------------------
WBR, Igor
Ratings: 0 negative/0 positive
Re: Вложенные класы
S-type
Автор

Сообщений: 2969
Дата регистрации: 24.04.2004
Igor Korolyov
Отвечая "в лоб" из двух статик методов невозможно сделать один который бы "работал так же".

Именно ответ на этот вопрос и интересовал.

В итоге, получилось так:

public static class MyClass
{
public static MyNestedClass1 MyNestedClass1 = new MyNestedClass1();
public static MyNestedClass2 MyNestedClass2 = new MyNestedClass2();
}
public class MyNestedClass
{
public string MyFunc()
{
return GetType().Name;
}
}
public class MyNestedClass1 : MyNestedClass
{
}
public class MyNestedClass2 : MyNestedClass
{
}

Правда, это уже не nested-классы, но это не важно. Важно, что появился this, и можно вынести какой то общий функционал в базовый класс.

P.S. Это просто шаблон, реальный код сложнее.
Ratings: 0 negative/0 positive
Re: Вложенные класы
S-type
Автор

Сообщений: 2969
Дата регистрации: 24.04.2004
Igor Korolyov
Для статиков всё не так - вызов статика всегда идёт через имя_типа.метод()

Не совсем так - есть одно исключение "методы расширения". Это статические методы, но они вызываются: переменная.метод().
Ratings: 0 negative/0 positive
Re: Вложенные класы
Аспид

Сообщений: 3475
Откуда: Москва
Дата регистрации: 01.04.2005
Да. Упустил что речь о статически классах. Я просто и не ожидал такого.
Ну... тогда посоветовал бы ТС, не увлекаться ими... да вообще забыть)))


------------------
Ratings: 0 negative/0 positive
Re: Вложенные класы
Igor Korolyov

Сообщений: 34580
Дата регистрации: 28.05.2002
S-type
Не совсем так - есть одно исключение "методы расширения". Это статические методы, но они вызываются: переменная.метод().

На самом деле это лишь "синтаксический сахар" - конструкция которая компилятором заменяется на ту самую кондовую StaticClass.MyExtensionMethod(this, ...)
Реально без префикса вызываются лишь статики этого же самого класса (ну или класса-предка), да и то лишь потому что в таком случае "контекст" очевиден - похоже как для обращения к инстанс членам без использования this изнутри этого же класса, или классов-потомков. Можно считать что тут тоже компилятор помогает, дописывая нужный префикс в виде ИмяКласса.

Аспид
Ну... тогда посоветовал бы ТС, не увлекаться ими...
И я про то же. У статиков весьма ограниченный круг разумного применения, и я чаще вижу неправильное их применение, нежели разумное. "Неправильное" не в том смысле что оно не скомпилируется, или не будет работать, а в том смысле что такой способ будет создавать больше проблем и неудобств, чем иметь плюсов.


------------------
WBR, Igor
Ratings: 0 negative/0 positive
Re: Вложенные класы
Igor Korolyov

Сообщений: 34580
Дата регистрации: 28.05.2002
S-type
Правда, это уже не nested-классы, но это не важно.

В данном случае нет совершенно никакой разницы вложенные будут эти классы или нет. В статик класс вполне можно вложить нестатик классы, равно как и наоборот. Разница лишь в области видимости ("внешний" класс может её ограничить), ну и собственно "имени" класса.
Опять же вложенные классы это весьма специфическая штука - у енё есть область разумного примененеия, и есть куча misuse вариантов "Классический" пример правильного применения вложенного класса - реализация энумератора (перечислителя). Обычно вложенные классы скрыты от внешнего мира, и при этом зачастую используют закрытые (private) члены своего "внешнего" класса. "Наружу" они если и выставляются, то как правило лишь в виде общедоступного (public) интерфейса, который они и реализуют.


------------------
WBR, Igor
Ratings: 0 negative/0 positive


Извините, только зарегистрированные пользователи могут оставлять сообщения в этом форуме.

On-line: 7 (Гостей: 7)

© 2000-2024 Fox Club 
Яндекс.Метрика