C#中如何让类的集合扩展方法访问该类的私有字段?
解决方案
C# 没有C++的friend关键字,但有以下几种符合语言规范的优雅实现方式:
方案1:将合并逻辑作为静态方法放在Solid类内部(最推荐,无额外配置)
Solid类自身的成员天然可以访问私有字段,直接在类内实现批量合并逻辑即可,不需要依赖扩展方法:
class Solid { private Faces[] f; // 其他原有逻辑 public static Solid Merge(IList<Solid> solids) { var allFaces = solids.SelectMany(s => s.f).ToArray(); return Build(allFaces); } private static Solid Build(Faces[] faces) { // 原有Build逻辑 } }
调用方式也很直观:var merged = Solid.Merge(solidList);
方案2:用Internal访问符 + InternalsVisibleTo特性(适配扩展方法语法要求)
如果你一定要保留扩展方法的调用形式,可以通过限定访问范围的方式暴露私有字段的访问权,这也是C#官方提供的类friend能力实现:
- 给
Solid加一个只读internal属性暴露私有字段f - 给程序集添加
InternalsVisibleTo特性,仅开放给扩展方法所在的程序集访问,不会泄露给其他无关代码
// 你的程序集的AssemblyInfo.cs里添加 [assembly: InternalsVisibleTo("你的扩展方法类所在的程序集名称")] // Solid类代码 class Solid { private Faces[] f; // 仅同程序集或指定友元程序集可访问 internal Faces[] Faces => f; } // 扩展方法类代码 public static class SolidExtensions { public static Solid Merge(this IList<Solid> solids) { var allFaces = solids.SelectMany(s => s.Faces).ToArray(); return Build(allFaces); } }
方案3:嵌套扩展方法类到Solid内部(完全不对外暴露私有字段)
如果不希望私有字段的访问权泄露给同程序集的其他类,可以把扩展方法类嵌套在Solid内部,嵌套类天然拥有外部类的私有成员访问权限:
class Solid { private Faces[] f; // 其他原有逻辑 public static class Extensions { public static Solid Merge(this IList<Solid> solids) { var allFaces = solids.SelectMany(s => s.f).ToArray(); return Build(allFaces); } } private static Solid Build(Faces[] faces) { // 原有Build逻辑 } }
调用前只需要引用Solid.Extensions这个命名空间即可,和普通扩展方法用法完全一致。
内容的提问来源于stack exchange,提问作者Jianjie
相关产品推荐
相关产品推荐

