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




  

相关话题

  实际开发中ref、out参数有多大作用? 
  面对很乱的代码,你会慢慢看,慢慢改,还是重写? 
  全世界有上千种编程语言,为什么程序员都只学习那几个主流语言? 
  低代码开发以后有前景么?会不会最后一地鸡毛? 
  为什么说 Java 比 C / C++ 慢? 
  CMake是不是阻碍了C++的发展? 
  作为程序员,是什么让你坚持不懈地学习?难道不累吗? 
  被家长逼学编程,虽然知道这个东西不错,但就是十分厌恶,怎么办? 
  码农们最常说的「谎言」有哪些? 
  带一堆指针的链式结构怎么写才好? 

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





© 2025-04-10 - tinynew.org. All Rights Reserved.
© 2025-04-10 - tinynew.org. 保留所有权利