百科问答小站 logo
百科问答小站 font logo



c#中没有友元类那么这种设计是否不太合理,如何修改才能得到更好的方案? 第1页

  

user avatar   Ivony 网友的相关建议: 
      

这是C#类型系统无法解决的问题。但是通常来说不那么追求洁癖的话也没什么太大的关系。

C#的友元只能到程序集的层面,没有类型层面上的友元。通常这种问题用internal interface解决(如果有继承关系也可以用protected interface),当然这个也没有办法细化到类型的级别,但一般够用。


顺便说一下什么叫做internal interface,这个要借助C#的一个特性,叫做显示接口实现。

显示接口实现有一个非常有用的特性,就是显示接口实现的成员其可见性等价于接口。这就带来一种手法:

       internal interface IFoo {   void SetName( string name ); }  public class MyClass : IFoo {   public Name { get; private set; }   void IFoo.SetName( string name ) => Name = name; }      

这样就使得,任何可以看到IFoo接口的类型,都可以调用SetName方法,而任何看不到IFoo接口的类型,都不能调用。


当然有人会说,为啥要这么麻烦?我直接写成这样不就好了?

         public Name { get; internal set; }      

这样的确可以,但是显示接口实现的好处在于更好的语义提示:

       public void ResetName( MyClass instance) =>   ((IFoo) instance).SetName( "" );      

这里的强转可以起到语义提示,我要干坏事了……



当然,未来C#里面会增加扩展属性(和扩展方法一样),到时候可以在很大程度上解决这个问题。当然不嫌丑的话,也可以用扩展方法解决。

要实现这一点,我们就必须把Equipment从Human剥离出来。然后用一个EquipmentContainer来管理这一个东西,很显然,当Equipment从Human剥离出来后,他的set的问题就被彻底解决了。因为很显然的,Human并没有设置Equipment,它本质上是被EquipAction所使用的。

在使用扩展方法的模式下,这会使得代码变得丑陋:

       internal sealed class EquipmentContainer {   public IEquipment Equipment{ get; set; } }  public static class EquipmentExtensions {   public static IEquipment GetEquipment( Human human )   {     return human.Features.Get<EquipmentContainer>().Equipment;// Features参考AspNetCore的设计。   }    internal static void SetEquipment( Human human, IEquipment equipment )   {     human.Features.Get<EquipmentContainer>().Equipment = equipment;   } }      

顺便说一下这个EquipmentContainer的意义在哪里,它的意义就在于,当你看不到这个类型的时候,你永远也没法给Human设置Equipment,如果我们不用这样一个中介而直接使用IEquipment,则因为Features方法是public的,导致任何人都可以设置Equipment




  

相关话题

  有 C 语言基础,选择 C#、C++、Java、Swift 中的哪一个进一步学习更合适? 
  工作经历里有C#是不是程序员一生的污点?加州各大公司除了“我软”招人是不是特别鄙视C#? 
  如何通俗地解释 C、C++、C#、Java、JavaScript、HTML、Python的用处? 
  做游戏不仅要编程能力还要计算机其它方面的知识吗? 
  非计算机专业自学C++,有什么书籍推荐? ? 
  “Facebook 开发的高性能PHP虚拟机 HHVM 比官方的 PHP解释器 快超过9倍”的说法是否属实? 
  感觉算法在程序员中快被吹上天了,如果只是搞编程的话,是不是没必要死磕算法? 
  掌握很多门计算机语言的人不会记串吗? 
  这篇博文c#比JAVA慢这么多 为什么? 
  Python 语言有什么奇技淫巧吗? 

前一个讨论
总会有人比你强,既然这样你是怎么做到保持自信的?
下一个讨论
UDP 和 TCP 的 socket 分别一般用在什么地方?





© 2024-12-22 - tinynew.org. All Rights Reserved.
© 2024-12-22 - tinynew.org. 保留所有权利