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

标签 c# generics interface encapsulation

有没有办法将字段定义为私有(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有一个公共(public),这个解决方案对我有用。但是有没有办法正确封装x.Name,以便Add可以修改x.Name,但是x.Name 无法在 BC 实例中修改?

最佳答案

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

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>类,它是为集合继承而设计的。

关于C#:将字段定义为私有(private)但可在泛型中修改,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10266731/

相关文章:

c# - .NET 中系统程序集的 CultureName

c# - 在声明中的对象初始化与构造函数中的初始化之间经历不同的行为

c# - 通过 NuGet 提供 App.config 文件

java - 为什么在 Annotation 接口(interface)中声明 Object 的非最终公共(public)方法?

pointers - Golang 反射 : Can't set fields of interface wrapping a struct

c# - mvc4 从表单中获取日期值

java - 查找泛型数组中的最大元素及其位置,并返回包含两者的数组

c# - 具有泛型类声明的命名空间约束

typescript - 如何基于通用类型 "T"初始化 TypeORM 存储库?

c# - 无法从用法中推断方法 'xyz' 的类型参数