C#:将字段定义为私有字段,但可在泛型中修改

本文关键字:字段 泛型 修改 定义 | 更新日期: 2023-09-27 18:31:51

有没有办法将字段定义为private但仍然可以使用包含类的泛型在方法中修改?

(对问题的长度表示歉意;我正在努力确定我所要求的确切内容)

具体来说,我目前有三个类ABC,具有以下要求:

  1. BC有一个名为 name 的字段,但A没有
  2. AC有一个方法Load(),但B没有
  3. BC的集合在自定义Add()方法中使用name,但A不使用此方法

这是我当前的解决方案:

public class BaseClass
{
    public SomeType Load() { ... }
}
public interface IClass {
    string Name {get; set;}
}
public class MyList : SomeCollection<IClass>
{
    // Depends on x.Name, and may modify Name before adding x to the collection
    public new void Add(IClass x) { ... }
}
public class A : BaseClass { ... }
public class B : IClass { ... }
public class C : BaseClass, IClass { ... }

如果Name有一个公共set,这个解决方案对我有用。但是有没有办法正确封装x.Name以便Add可以修改x.Name,但在BC的情况下不能修改x.Name

C#:将字段定义为私有字段,但可在泛型中修改

简短的回答是否定的。不能有选择地向特定类公开成员,并且MyListIClass没有继承关系。但是,您可以做的是创建一个额外的内部接口(或者可能IClass内部接口)来公开 Name 属性并显式实现它。这意味着,为了读取/写入 Name 属性,您需要将实例强制转换为内部接口,这只能在它定义的程序集中实现。

internal interface IClassName { string Name { get; set; } }
public class MyList : Collection<IClass>
{
    protected override void InsertItem(int index, IClass item)
    {
        var className = item as IClassName;
        if (className != null)
        {
            // do something with className.Name ...
        }
        base.InsertItem(index, item);
    }
}
public class B : IClassName { string IClassName.Name { get; set; } }

请注意,我没有使用 new 关键字来绕过基类的 Add 方法,因为这会覆盖多态性(例如,如果您强制转换 MyList 的实例来IList<IClass>将调用Add的原始实现 - 这很糟糕。相反,我将重写 Collection<T> 类中的相应方法,该方法专为集合继承而设计。