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




  

相关话题

  如何评价微软新推出的 .NET 5? 
  为什么说 Java 比 C / C++ 慢? 
  C 语言线程间怎么通信? 
  编程是否存在终极问题? 
  程序员是一群什么样的人? 
  Markdown 标准化的阻碍在哪里? 
  只给:代码和大道理,不给详细Example(或者demo、sample)的教材作者是怎么想的? 
  你最喜欢的中国编程网站是哪些? 
  要设计一段C++程序将这组数按要求重新排序时,有哪些好的算法? 
  为什么安装不了java?这是啥问题? 

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





© 2024-11-21 - tinynew.org. All Rights Reserved.
© 2024-11-21 - tinynew.org. 保留所有权利