gpt4 book ai didi

c# - C# 中的通用标识映射。不想要公共(public)构造函数

转载 作者:太空狗 更新时间:2023-10-29 22:25:03 24 4
gpt4 key购买 nike

我正在尝试实现 identity map使用泛型。我有一个抽象类 Entity,在我的 Entity 映射上有一个派生约束。由于我的 map 需要能够实例化实体,因此我的 map 还具有构造函数约束。

但是,为了使 map 有用,实体子类不应该能够从客户端代码实例化,这意味着我需要一个内部构造函数而不是公共(public)构造函数。但是,这与构造函数约束冲突。

有什么我想念的吗?有什么方法可以重构它以获得预期的结果吗?

以下代码按原样编译,但理想情况下,Entity 的子类的构造函数应该是内部的:

public abstract class Entity
{
public int Id { get; protected internal set; }
}

public sealed class Widget : Entity
{
// Client code should not be allowed to instantiate entities.
// But the constraints on EntityMap require that entities have
// a public constructor.
public Widget() { }
}

public sealed class Gadget : Entity
{
public Gadget() { }
}

// The new() constraint is required so that Get() can instantiate Ts.
public class EntityMap<T> where T : Entity, new()
{
private Dictionary<int, T> _entities = new Dictionary<int, T>();
private object _getLock = new object();

public T Get(int id)
{
lock (_getLock)
{
if (!_entities.ContainsKey(id))
_entities.Add(id, new T() { Id = id });
}

return _entities[id];
}

// Client code should not be allowed to instantiate maps.
internal EntityMap() { }
}

// Ideally, the client would only be able to obtain Entity
// references through EntityMaps, which are only accessible
// through the ApplicationMap.
public static class ApplicationMap
{
public static EntityMap<Widget> Widgets = new EntityMap<Widget>();
public static EntityMap<Gadget> Gadgets = new EntityMap<Gadget>();
}

最佳答案

不需要构造函数约束,而是传递 Func<T>到 map 构造函数。这样构造函数可以是内部的,但 map 仍然可以有效地调用它:

public class EntityMap<T> where T : Entity
{
private readonly Dictionary<int, T> _entities = new Dictionary<int, T>();
private readonly object _getLock = new object();
private readonly Func<T> _entityGenerator;

public T Get(int id)
{
lock (_getLock)
{
T ret;
if (!_entities.TryGetValue(id, ret))
{
ret = entityGenerator();
newEntity[id] = ret;
ret.Id = id;
}

return ret;
}
}

internal EntityMap(Func<T> entityGenerator)
{
_entityGenerator = entityGenerator;
}
}

然后初始化:

EntityMap<Widget> widgetMap = new EntityMap(() => new Widget());

您可以将其设为 Func<int, T>相反,让委托(delegate)人负责创建具有正确 ID 的实体。这样您就可以将您的 ID 正确设置为只读,将其作为 Entity 的参数。构造函数。

(顺便说一句,我冒昧地让你的 Get 方法更有效。)

关于c# - C# 中的通用标识映射。不想要公共(public)构造函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1406107/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com