C#中如何在管理类中设置对象列表内私有字段的值?
如何在ExampleClassManager中为ExampleClass的私有_id字段赋值?
没问题,虽然_id是私有字段,但我们有几种合理的方式能在ExampleClassManager里给它赋值,下面给你拆解几个常用方案,按推荐程度排序:
1. 给ExampleClass添加带参数的构造函数(最推荐)
这是最符合面向对象封装原则的做法,在创建ExampleClass实例时就通过构造函数把_id初始化好,外部完全不需要接触私有字段:
public class ExampleClass { private string _id; // 带参数的构造函数,用于初始化_id public ExampleClass(string id) { _id = id; } } public class ExampleClassManager { List<ExampleClass> exampleClassList = new List<ExampleClass>(); public void AddNewExample(string id) { // 创建实例时直接传入_id,完成赋值 exampleClassList.Add(new ExampleClass(id)); } }
2. 添加公共属性或Setter方法(灵活度高)
如果需要在对象创建后修改_id,可以给ExampleClass加一个只开放赋值的公共属性,或者专门的Setter方法,既保持封装性,又能满足修改需求:
方案2.1:使用公共属性
public class ExampleClass { private string _id; // 只开放set的属性,外部只能赋值不能直接读取(如果需要读取可以加get) public string Id { set => _id = value; // 若需读取:get => _id; } } public class ExampleClassManager { List<ExampleClass> exampleClassList = new List<ExampleClass>(); public void UpdateExampleId(int itemIndex, string newId) { if (itemIndex >= 0 && itemIndex < exampleClassList.Count) { // 通过属性给_id赋值 exampleClassList[itemIndex].Id = newId; } } }
方案2.2:使用Setter方法
public class ExampleClass { private string _id; // 专门的方法用于设置_id public void SetId(string id) { _id = id; } } public class ExampleClassManager { List<ExampleClass> exampleClassList = new List<ExampleClass>(); public void UpdateExampleId(int itemIndex, string newId) { if (itemIndex >= 0 && itemIndex < exampleClassList.Count) { // 通过方法给_id赋值 exampleClassList[itemIndex].SetId(newId); } } }
3. 将_id改为internal(同程序集场景可用)
如果ExampleClass和ExampleClassManager在同一个程序集里,可以把_id的访问修饰符改成internal,这样同程序集内的类都能直接访问它,但外部程序集不行:
public class ExampleClass { // 改为internal,同程序集内可直接访问 internal string _id; } public class ExampleClassManager { List<ExampleClass> exampleClassList = new List<ExampleClass>(); public void SetExampleId(int itemIndex, string id) { if (itemIndex >= 0 && itemIndex < exampleClassList.Count) { // 直接给_id赋值 exampleClassList[itemIndex]._id = id; } } }
⚠️ 注意:这种方式会降低封装性,只适合确实需要同程序集内多个类访问该字段的场景,不要滥用。
4. 使用反射(不推荐,仅特殊场景)
反射可以绕过访问修饰符直接修改私有字段,但这种方式性能差、代码脆弱(字段名修改就会出错),还破坏了封装原则,除非是序列化、单元测试等特殊场景,否则绝不推荐:
public class ExampleClassManager { List<ExampleClass> exampleClassList = new List<ExampleClass>(); public void SetIdViaReflection(int itemIndex, string id) { if (itemIndex >= 0 && itemIndex < exampleClassList.Count) { var targetExample = exampleClassList[itemIndex]; // 获取私有字段的信息 var fieldInfo = typeof(ExampleClass).GetField( "_id", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance ); // 给字段赋值 fieldInfo?.SetValue(targetExample, id); } } }
内容的提问来源于stack exchange,提问作者Nungwe
相关产品推荐
相关产品推荐

