百科问答小站 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




  

相关话题

  何时使用 Protected 继承? 
  对象和实例的在不同编程语言中的有什么区别? 
  面向对象编程的下一阶段是什么? 
  c#入门书籍有推荐吗? 
  PHP的未来在哪? 
  数学/算法:正方形内有5个点,为什么最近点对的距离小于边长? 
  在校生为了面试,有必要强行记住一些复杂算法如红黑树、KMP等的实现吗? 
  作为一个有理想的程序员,必读的书都有哪些? 
  如何理解 “c++缺少对象级别的消息发送机制” 这句话? 
  GitHub 上有哪些适合新手跟进的优质项目? 

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





© 2024-05-20 - tinynew.org. All Rights Reserved.
© 2024-05-20 - tinynew.org. 保留所有权利