【发布时间】:2019-03-05 22:01:30
【问题描述】:
我正在为开发人员开发一个库,他们必须创建一个继承自我创建的类的类。
这个基类本质上为开发者管理一个对象数组,但是开发者可以指定他们希望基类管理的这些对象的类型。
所以开发人员基本上只是告诉基类创建一个数组,然后只有对该数组的只读访问权限。基类将(取决于应用程序的状态)从数组中添加或删除对象。
我一直在寻找合适的数据类型来存储这样的东西。我试过ref 和out 但这让我无处可去。我得到的最接近的是Dictionary,但这个想法失败了,因为 C# 实际上只是将值复制到字典中,而不是引用或指向它。
这是我拼凑的一个简单示例:
public static void Main()
{
Derived d = new Derived();
d.InitBase();
d.Init();
d.CheckArray();
d.AddElement<GenericObject>(new GenericObject{ i = 2 });
d.CheckArray();
}
public class Base {
Dictionary<Type, List<object>> ArrayReferences;
public void InitBase() {
ArrayReferences = new Dictionary<Type, List<object>>();
}
protected ReadOnlyCollection<T> RegisterArray<T>() {
List<object> managedArray = new List<object>();
ArrayReferences.Add(typeof(T), managedArray);
return Array.AsReadOnly(managedArray.Select(s => (T)s).ToArray());
}
public void AddElement<T>(T obj) {
ArrayReferences[typeof(T)].Add(obj);
}
public void RemoveElement<T>(T obj) {
ArrayReferences[typeof(T)].Remove(obj);
}
}
public class Derived: Base {
ReadOnlyCollection<GenericObject> arr;
public void Init() {
arr = RegisterArray<GenericObject>();
}
public void CheckArray() {
Console.WriteLine(arr.Count());
}
}
public class GenericObject {
public int i = 0;
}
输出:
0
0
字典显然不会像我想要的那样将值存储为引用。那么 C# 还有哪些其他技术,或者这根本不可能?也不确定unsafe 会引起多少问题,所以我很害怕走那条路。
【问题讨论】:
-
优先组合而不是继承。与其制作某人为了使用而继承的集合,不如将您的集合密封,并让人们创建它的一个实例以使用该集合。您的派生类不会改变类型的行为,它们只是在使用它。也不要创建方法来初始化对象。该对象应在其构造函数中初始化。
-
当您在派生类中获得 arr 时,它会在您调用 RegisterArray 的位置创建一个全新的对象数组。您正在向字典中添加对象,但它们没有被添加到该数组中,因为它只是及时的快照。当前(在这种情况下为空)引用集(如果是引用类型)的快照。
-
问题:为什么需要派生类(而不是封装)?以及您的“派生”(或父母,如果您这样做的话)想如何使用这些快照?
-
@monty 基类将存在于开发人员不应访问的 dll 中。我开发人员创建自己的派生类,他们将在基类中拥有更多与状态相关的代码。
-
@Servy 会试一试。这对我来说有点开箱即用,但如果我理解正确,我认为它会完成这项工作。
标签: c# dictionary generics