C# 在实体类上实现标记属性
当我在类库中创建实体时,我倾向于添加一个C# 在实体类上实现标记属性,c#,.net,tags,properties,C#,.net,Tags,Properties,当我在类库中创建实体时,我倾向于添加一个标记属性,用户和扩展库可以使用该属性来存储对象中的任意数据。现在,我正在寻找在我的类库中实现这样一个标记属性的最佳方法,以及原因 在System.Windows.Forms中,Microsoft使用对象标记{get;set;}作为签名,但它看起来太有限了,因为在任何时候只有一个人可以使用该标记 我还考虑了HashTable标记{get;}以允许任何人按键设置和检索任何数据,但对于类库来说,它似乎太“公开”了。然后,IDictionary标记{get;}将是
标记
属性,用户和扩展库可以使用该属性来存储对象中的任意数据。现在,我正在寻找在我的类库中实现这样一个标记属性的最佳方法,以及原因
在System.Windows.Forms中,Microsoft使用对象标记{get;set;}
作为签名,但它看起来太有限了,因为在任何时候只有一个人可以使用该标记
我还考虑了HashTable标记{get;}
以允许任何人按键设置和检索任何数据,但对于类库来说,它似乎太“公开”了。然后,IDictionary标记{get;}
将是一个更好的选择,但两者都允许任何人清除我想要避免的整个字典。同样,HashTable和IDictionary都只允许您使用对象
实例,在这些实例中,泛型可能是更好的选择。但是Dictionary标签{get;}
显然不适用于所有可能的消费者
那么,该走哪条路
编辑:
正如下面Timwi正确建议的那样,我不希望不同的用户类能够相互干扰。我假设有很多实体类,只有少数几个类需要存储相关数据。您可以扩展IDictionary
或Dictionary
,使其可变。然而,有些事情告诉我,一般来说,你可能在这件事上做错了。松散类型的集合在交付端总是很有趣
这只是我的2c,有点主观,但我避免松散类型,除非它们是必要的。像这样的可能吗
public class Taggable :ITaggable
{
private IDictionary<string, object> _tags = new Dictionary<string, object>();
public void AddTag(string key, object tag)
{
_tags.Add(key,tag);
}
public bool IsTag(string key)
{
return _tags.ContainsKey(key);
}
public T GetTag<T>(string key)
{
return (T) _tags[key];
}
public void RemoveTag(string key)
{
_tags.Remove(key);
}
}
公共类可标记:可标记
{
私有IDictionary_标记=新字典();
public void AddTag(字符串键、对象标记)
{
_标签。添加(键、标签);
}
公共布尔IsTag(字符串键)
{
返回_tags.ContainsKey(键);
}
公共T GetTag(字符串键)
{
返回(T)_标签[键];
}
public void RemoveTag(字符串键)
{
_标签。移除(键);
}
}
虽然我没有包括它,但所有四种方法都在接口上
任何人都不能“滥用”集合,因为他们需要知道密钥。您的要求之一似乎是访问实体对象的各个线程或进程不应该能够看到彼此的私有数据。恐怕这是一个很好的迹象,表明私有数据不应该位于它们共享的实体对象中。相反,每个进程都应该有自己的私有数据。它实际上不必位于实体对象本身,但可以通过专用字典与实体对象关联:
private Dictionary<Entity, object> myPrivateEntityData = new ...;
然后您可以轻松访问myPrivateEntityData[someEntity].NoOne
(等),它将正常工作,并且不会引发异常,因为密钥不在那里,但是,如果您想检查它是否存在,您仍然可以使用ContainsKey
。但是想象一下可能的情况,即有许多实体对象,但只有一个或几个用户类存储相关数据。为每个实体提供一个小词典不是比为每个用户提供一个大词典更快吗?是的,这就产生了许多小词典。也许,假设一个用户类可能希望为几乎每个实体存储一个引用,可以找到一些折衷方案?
private Dictionary<Entity, SuperSecretSpecialData> myPrivateEntityData = new ...;
private sealed class SuperSecretData {
public bool NoOne;
public int ElseBut;
public string MeCan;
public DateTime SeeThis;
}
public sealed class AutoDictionary<TKey, TVal> : Dictionary<TKey, TVal> where TVal : class, new()
{
public new TVal this[TKey key]
{
get
{
if (!ContainsKey(key))
Add(key, new TVal());
return base[key];
}
set
{
base[key] = value;
}
}
}
private AutoDictionary<Entity, SuperSecretSpecialData> myPrivateEntityData = new ...;