Большинство программистов-консультантов отстой , и им нельзя разрешать писать производственный код.
ИМХО - Вероятно, около 60% или более
Идея интерфейса состоит в том, чтобы представлять контракт, а не реализацию.
Я не могу вспомнить, действительно ли IL разрешает статические методы с реализациями в интерфейсах - У меня есть скрытое подозрение, что это так - но это несколько запутывает концепцию.
Я понимаю вашу точку зрения - иногда полезно знать, какие вспомогательные методы доступны, которые связаны с интерфейсом (а методы расширения особенно актуальны там), но я лично все равно хотел бы выделить их в отдельный класс, просто чтобы ментальная модель была чистой.
Я сталкивался с этим несколько раз и провел небольшое исследование. Печально то, что IL действительно поддерживает это. Я так расстроился из-за этого, что написал об этом в блоге. Вы можете найти его здесь .
Для вашей цели будет гораздо лучше отделить интерфейс плагина от реализации загрузчика плагина: это сделает ваш дизайн менее связанным и более связным (что снизит сложность).
Что касается «статических методов в интерфейсе», см. this .
И в качестве примечания: вы действительно не хотите изобретать еще одну архитектуру плагина: взгляните на MEF .
Интерфейс - это всего лишь интерфейс. Он не предназначен для описания поведения. Когда класс реализует интерфейс, он просто говорит: «Я обещаю, что я предоставлю методы / события / и т. Д. С этими сигнатурами».
Вам нужен интерфейс без статического метода и абстрактный базовый класс, реализующий интерфейс и статический метод. Затем другие классы могут наследовать от базового класса и изменять реализации методов интерфейса. Но даже это сомнительный проект.
статические методы связаны с типом, в котором они объявлены, и не имеют отношения к переопределению. Если бы вы смогли прикрепить статический метод к интерфейсу, вам пришлось бы ссылаться на него через сам интерфейс, например ITaskPlugin.GetPlugins (...)
Что вы хотите сделать, это либо:
1) Поместите свой метод в абстрактный базовый класс, так как интерфейсы не предназначены для хранения кода реализации, или
2) Создайте метод расширения, который применяется к интерфейсу, и тогда у вас будет доступ к нему без использования базовый класс.
Назначение интерфейса - объявить интерфейс объекта, через который к нему можно получить доступ. Из-за того, что это его единственная цель, не имеет смысла разрешать размещение кода в интерфейсе. Если вы все же хотите добавить код в интерфейс, вы можете использовать методы расширения.
Прочтите мою запись в блоге о статических методах, реализованных в интерфейсах (извините за бесстыдную ссылку на себя)
[удалена неработающая ссылка http: / ...]
сайт dotnetjunkies ткнул totaldevpro ... так что версия, кэшированная Google, является единственной доступной
Изменить: Я вставил кешированную версию ниже, которую нашел:
[...]
Используйте ILAsm для компиляции следующего:
.assembly extern mscorlib {
.publickeytoken = (B7 7A 5C 56 19 34 E0 89 )
.ver 2:0:0:0
}
.assembly MaLio.StaticInterface{
.hash algorithm 0x00008004
.ver 0:1:0:0
}
.module MaLio.StaticInterface.dll
.imagebase 0x00400000
.file alignment 0x00001000
.stackreserve 0x00100000
.subsystem 0x0003
.corflags 0x00000001
.class interface public abstract auto ansi MaLio.IMyInterface {
.method public hidebysig newslot abstract virtual instance void DoInstanceWork() cil managed {
}
.method public hidebysig static void DoStaticWork() cil managed {
ldstr "Static"
call void [mscorlib]System.Console::WriteLine(string)
ret
}
}
.class public auto ansi beforefieldinit MaLio.MyClass extends [mscorlib]System.Object implements MaLio.IMyInterface {
.method public hidebysig newslot virtual final instance void DoInstanceWork() cil managed {
ldstr "Instance"
call void [mscorlib]System.Console::WriteLine(string)
ret
}
.method public hidebysig specialname rtspecialname instance void .ctor() cil managed {
ldarg.0
call instance void [mscorlib]System.Object::.ctor()
ret
}
}
Затем этот код можно вызвать
System.Type myInterface = typeof(MaLio.IMyInterface);
// show that we really are dealing with an interface
if (myInterface.IsInterface) {
System.Reflection.MethodInfo staticMethod = myInterface.GetMethod("DoStaticWork");
staticMethod.Invoke(null, null);
}
Intellisense (VS) здесь не работает должным образом. Он распознал статический метод как метод экземпляра интерфейса, и код (если он следует подсказкам intellisense) выглядит так, как если бы он собирался скомпилировать. Компилятор C # (MS C #) не компилирует код, поскольку C # не поддерживает реализованные статические методы на интерфейсах и может быть вызван из C # только через отражение.
Я не тестировал с другими IDE, такими как SharpDevelop ... поэтому пока не знаю, как бы он поступил в этой ситуации.