如何在类中将内部数据以只读形式对外暴露?
你遇到的Inconsistent accessibility: property type错误,核心原因很好理解:你把返回类型是internal的Data结构体,通过public的属性暴露给外部了。C#不允许这种矛盾的情况——外部代码(当前程序集之外)能看到这个public属性,但却看不到它的返回类型Data,这就造成了可访问性的冲突。
既然你想把Data留在MyClass内部,同时让外部能以只读形式获取数据,这里有几个贴合需求的实现方案:
方案1:直接暴露具体数据字段(最简洁)
如果外部不需要感知Data这个结构体的存在,只是需要读取里面的SomeData,那完全没必要暴露整个结构体。直接在MyClass里提供对应只读属性即可:
public class MyClass { private Data _data; // 直接把内部Data的字段暴露为只读属性 public int SomeData => _data.SomeData; internal struct Data { public int SomeData; } }
这种方式既保持了Data的内部可见性,又满足了外部只读访问的需求,代码最简洁直观。
方案2:将Data设为public但只读(需要暴露类型时用)
如果外部需要知道Data这个类型(比如需要传递这个类型的实例),可以把Data改为public,但把它的成员设为只读,同时利用结构体的值类型特性来保证内部数据不被修改:
public class MyClass { private Data _data; // 返回Data的副本,外部修改副本不会影响内部的_data public Data Data => _data; public struct Data { // 用只读字段或者get-only属性 public readonly int SomeData; // 内部构造函数,只有MyClass能创建/修改Data实例 internal Data(int someData) { SomeData = someData; } } // 内部修改数据的方法示例 public void UpdateData(int newValue) { _data = new Data(newValue); } }
这里要注意:结构体是值类型,Data属性返回的是_data的副本,所以外部即使修改返回的Data实例,也不会影响MyClass内部的_data。再加上Data的构造函数是internal,外部无法创建新的Data实例,完全保证了内部数据的可控性。
方案3:用接口封装只读操作(更灵活的场景)
如果以后Data可能扩展更多字段,或者需要统一的只读访问契约,可以定义一个public的只读接口,让Data实现它,然后属性返回这个接口:
public interface IReadOnlyData { int SomeData { get; } } public class MyClass { private Data _data; // 返回只读接口,外部只能调用接口定义的只读成员 public IReadOnlyData Data => _data; internal struct Data : IReadOnlyData { public int SomeData { get; set; } } }
这种方式扩展性更强,即使Data内部增加了可修改的成员,外部通过IReadOnlyData也只能看到只读的部分。
内容的提问来源于stack exchange,提问作者WDUK

