Страницы

Поиск по вопросам

вторник, 31 декабря 2019 г.

Поместить static/const в интерфейс или абстрактный класс C#

#c_sharp #const #интерфейс


Как можно определить интерфейс или абстрактный класс, который вынудит реализовывать
публичную константу (отображаемое пользователям наименование класса, нужно вывести
список до того как юзверь тыкнет в заинтересовавший его класс) и статический метод
(например GetInstance)?
    


Ответы

Ответ 1



Никак. Это не поддерживается языком. Вы можете сэмулировать константу уровня экземпляра класса через свойство с одним лишь геттером: interface ISomething { string ClassName { get; } } Статические методы в интерфейс не вписываются никак, вообще. В текущей концепции вы получаете доступ к статическому объекту по имени класса, а не по экземпляру объекта. А поддержка интерфейсов реализована обычным образом, через таблицы виртуальных методов. Тем не менее, в будущих версиях языка возможны изменения, разрешающие схожую функциональность (generic-условия на наличие статического метода). Design team языка C# обсуждает эту возможность. Вот пример того, как динамически проверить наличие статического метода: interface ISomething { } static class SomethingChecker { public static Func CheckAndGetBuider() where T : ISomething { var type = typeof(T); var builder = type.GetMethod("GetInstance", BindingFlags.Public | BindingFlags.Static); // а есть ли такой метод? if (builder == null) throw new Exception(); // а не требует ли метод generic-аргумент? if (builder.IsGenericMethod) throw new Exception(); // а не требует ли метод параметров? if (builder.GetParameters().Length != 0) throw new Exception(); // а подходящий ли тип результата? if (!type.IsAssignableFrom(builder.ReturnType)) throw new Exception(); // все проверки пройдены return () => (T)builder.Invoke(null, null); } } Здесь рабочий пример использованием: http://ideone.com/bPyoEf

Ответ 2



На уровне языка это реализовать невозможно. Если вы хотите задать некое свойство для всего класса, то можно вместо статического свойства типа string завести статическое свойство типа IDictionary. Пусть каждый класс в статическом конструкторе записывает в словарь своё название. Если вы используете dependency injection, то подобное свойство можно добавить как мета-информацию к классу, например, с помощью атрибутов. Если при работе с этим классом всегда есть экземпляр, то можно добавить нестатическое свойство. В этом случае свойство не будет статическим, но смысл останется прежним. В целом, возможных реализаций много, и что вы выберете — зависит от вашей конкретной ситуации: как вы используете значение, когда и как создаются экземпляры и т.п.

Комментариев нет:

Отправить комментарий