Страницы

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

суббота, 29 декабря 2018 г.

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

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


Ответ

Никак.
Это не поддерживается языком.
Вы можете сэмулировать константу уровня экземпляра класса через свойство с одним лишь геттером:
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

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

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