实现接口和在C#中应用属性之间的区别

Rem*_*tec 21 c# attributes interface

这可能是一个愚蠢的问题,但无论如何,我会问,

我正在阅读"OOP揭秘:Jim Keogh和Mario Giannini的自学指南"第11章,其中涵盖了界面.本书中的示例是C++.

我注意到C++使用ISerializable来创建一个可序列化的类,你可以在C#中实现,只需使用[Serializable]属性来定义类.

这里的关键区别是什么?是否使用接口,您必须提供实现,就好像您归因于编译器将为您实现的实现?

我想通过[Serializable]属性,.Net框架使用反射来从实际对象生成序列化对象.

那就是说在这种情况下有可能有一个[Disposable]属性或者在框架之上使用我的理论不知道如何实际处理一个对象因此你必须自己做?

将不胜感激澄清.

谢谢.

Fáb*_*sta 11

很久以前在遥远的星系中......没有属性或编译器支持类元数据,所以开发人员试图实现自己的.我们的祖先制定的方法之一是宣布标记接口.

所以,回答你的问题:自定义属性是标记接口的"演变".你可以使用两者.但请注意,如果要强制实现对象实现特定方法,则使用简单明了的接口.这是IDisposable有效的,它迫使你实现一个名为的方法Dispose().[Serializable](可能ISerializable在你的C++示例中)并没有强制你实现任何东西,因为运行时只会读取该声明并执行其任务(即序列化对象).

请注意,C#也有一个ISerializable接口...它是为了让您编写自定义序列化代码,然后由运行时调用.请注意,它不是标记接口,也不是[Serializable]属性的替代,因为您仍需要使用属性标记类以使序列化生效.

  • 使用泛型和扩展方法,"Marker Interfaces"仍然很棒.它们允许使用接口作为通用约束; 目前属性无法实现的东西. (4认同)
  • 那么`ISerializable`接口允许你实现自定义方法,而不是使用基于默认反射的Serializtion过程.我知道的.Net中唯一的标记接口是ASP.Net的"INamingContainer". (3认同)

Mar*_*ell 7

属性通常提供有关类型或成员的其他元数据 ; 关于允许的内容(const值等)有很大的限制,Eric Lippert提供了一些关于接口和属性之间差异的想法,这可能是有启发性的.

接口还有一些其他方面:

  • 他们可以有多个成员
  • 接口背后是一些实现(这很关键)
  • 你可以使用接口进行抽象(而不是属性)

然而; 在缺点方面,一旦类型实现了接口,所有子类型也通过继承实现该接口.对比度属性,可以继承但不想成为.

仅仅因为Foo是可序列化的,这并不意味着Bar(:Foo)必须是可序列化的; 所以很高兴能够在每个级别定义 - 虽然实际上我不认为这BinaryFormatter应该是mots序列化代码的关键部分(尽管我会咬我的舌头).

实际上,如果你检查IL,你会发现它实际上[Serializable] 并没有作为属性写入 - 它是一个CLI标志(一些编译器魔术).但这并没有改变事实.

如果您需要做的只是表达元数据(关于类型/成员的事实),属性是理想的.如果需要表达行为/ API,那么接口.


kem*_*002 6

大多数属性仅在运行时检查.在编译时有一些检查(参见下面提到的条件属性).在大多数情况下,使用属性,您必须使用反射来查看对象是否拥有它并决定从那里做什么.

接口是编译器实现.使用接口,您可以要求参数为方法等实现它.

属性:http: //msdn.microsoft.com/en-us/library/z0w1kczw.aspx

接口:http: //msdn.microsoft.com/en-us/library/ms173156.aspx

  • 那不是真的.*在编译时检查某些*属性,例如`[Conditional]`.但是你无法在编译时实现自己的属性(除非你使用像PostSharp这样的工具). (3认同)