Почему не был должен, C# (или.NET) позволяют нам помещать статический/общий метод в интерфейсе?

Большинство программистов-консультантов отстой , и им нельзя разрешать писать производственный код.

ИМХО - Вероятно, около 60% или более

8
задан Community 23 May 2017 в 10:30
поделиться

7 ответов

Идея интерфейса состоит в том, чтобы представлять контракт, а не реализацию.

Я не могу вспомнить, действительно ли IL разрешает статические методы с реализациями в интерфейсах - У меня есть скрытое подозрение, что это так - но это несколько запутывает концепцию.

Я понимаю вашу точку зрения - иногда полезно знать, какие вспомогательные методы доступны, которые связаны с интерфейсом (а методы расширения особенно актуальны там), но я лично все равно хотел бы выделить их в отдельный класс, просто чтобы ментальная модель была чистой.

11
ответ дан 5 December 2019 в 07:36
поделиться

Я сталкивался с этим несколько раз и провел небольшое исследование. Печально то, что IL действительно поддерживает это. Я так расстроился из-за этого, что написал об этом в блоге. Вы можете найти его здесь .

6
ответ дан 5 December 2019 в 07:36
поделиться

Для вашей цели будет гораздо лучше отделить интерфейс плагина от реализации загрузчика плагина: это сделает ваш дизайн менее связанным и более связным (что снизит сложность).

Что касается «статических методов в интерфейсе», см. this .

И в качестве примечания: вы действительно не хотите изобретать еще одну архитектуру плагина: взгляните на MEF .

2
ответ дан 5 December 2019 в 07:36
поделиться

Интерфейс - это всего лишь интерфейс. Он не предназначен для описания поведения. Когда класс реализует интерфейс, он просто говорит: «Я обещаю, что я предоставлю методы / события / и т. Д. С этими сигнатурами».

Вам нужен интерфейс без статического метода и абстрактный базовый класс, реализующий интерфейс и статический метод. Затем другие классы могут наследовать от базового класса и изменять реализации методов интерфейса. Но даже это сомнительный проект.

1
ответ дан 5 December 2019 в 07:36
поделиться

статические методы связаны с типом, в котором они объявлены, и не имеют отношения к переопределению. Если бы вы смогли прикрепить статический метод к интерфейсу, вам пришлось бы ссылаться на него через сам интерфейс, например ITaskPlugin.GetPlugins (...)

Что вы хотите сделать, это либо:

1) Поместите свой метод в абстрактный базовый класс, так как интерфейсы не предназначены для хранения кода реализации, или

2) Создайте метод расширения, который применяется к интерфейсу, и тогда у вас будет доступ к нему без использования базовый класс.

0
ответ дан 5 December 2019 в 07:36
поделиться

Назначение интерфейса - объявить интерфейс объекта, через который к нему можно получить доступ. Из-за того, что это его единственная цель, не имеет смысла разрешать размещение кода в интерфейсе. Если вы все же хотите добавить код в интерфейс, вы можете использовать методы расширения.

0
ответ дан 5 December 2019 в 07:36
поделиться

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

[удалена неработающая ссылка 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 ... поэтому пока не знаю, как бы он поступил в этой ситуации.

2
ответ дан 5 December 2019 в 07:36
поделиться
Другие вопросы по тегам:

Похожие вопросы: