C# 需要一个带有我自己的自定义对类型的dict吗?

C# 需要一个带有我自己的自定义对类型的dict吗?,c#,dictionary,C#,Dictionary,KeyValuePair没有实现INotifyPropertyChanged,因此我实现了自己的Pair类型,但我想在字典中使用它 最简单的方法是什么 这就是交易。在我的代码中,我需要一个带有键/值对的字典。这实际上不需要被观察到 不过,我有一个编辑窗口,它在数据网格中显示这个dict。这需要是可观察的,以便数据网格能够发挥其魔力 因此,我所做的是使编辑窗口接受任何可枚举的对: public ObservableCollection<Pair<string,object&g

KeyValuePair
没有实现
INotifyPropertyChanged
,因此我实现了自己的
Pair
类型,但我想在字典中使用它

最简单的方法是什么


这就是交易。在我的代码中,我需要一个带有键/值对的字典。这实际上不需要被观察到

不过,我有一个编辑窗口,它在数据网格中显示这个dict。这需要是可观察的,以便数据网格能够发挥其魔力

因此,我所做的是使编辑窗口接受任何可枚举的对:

    public ObservableCollection<Pair<string,object>> Variables { get; private set; }

    public VariablesWindow(IEnumerable<Pair<string, object>> vars)
    {
        Variables = new ObservableCollection<Pair<string, object>>(vars.DeepCopy());
因此,我添加了以下两种辅助方法:

    private static IEnumerable<Pair<TKey, TValue>> Dict2Enum<TKey, TValue>(Dictionary<TKey, TValue> dict)
    {
        return dict.Select(i => new Pair<TKey, TValue>(i.Key, i.Value));
    }

    private static Dictionary<TKey, TValue> Enum2Dict<TKey, TValue>(IEnumerable<Pair<TKey, TValue>> collection)
    {
        return collection.ToDictionary(p => p.Key, p => p.Value);
    }
private静态IEnumerable Dict2Enum(Dictionary dict)
{
返回dict.Select(i=>newpair(i.Key,i.Value));
}
私有静态字典Enum2Dict(IEnumerable集合)
{
返回collection.ToDictionary(p=>p.Key,p=>p.Value);
}
不过似乎有点贵。我现在在收集两次。一次是将字典转换为可枚举项,然后再次进行深度复制,以便在用户点击save之前不会更改变量,然后我将该可枚举项转换为可观察的集合


以下是一个可作为参考的示例:


您是否正在尝试通知值更改?如果是这样,我会考虑编写一个<代码>包装器< /代码>类,它支持<代码> NoTyFyPryTyType ,然后使用(例如)代码>字典< /C> >(用于支持更改通知的String/int)字典。 请注意,这意味着任何保留对包装器的引用的人都将看到对值所做的更改——这是您必须非常小心的事情

编辑:要在我的评论上有所扩展

如果您还希望能够编辑密钥,我怀疑您会发现,对于可变的TKey/TValue对,您将需要一个
字典
。您将需要支持
INotifyPropertyChanging
以及
INotifyPropertyChanged
,它会变得很麻烦。。。您可能需要按
INotifyPropertyChanging
上的键将其删除,然后在
INotifyPropertyChanged
上重新添加它。毫无疑问,如果中途放弃改变,事情会变得一团糟。如果一个键重写了另一个键,您还需要确定希望发生什么。。。然后更改了原始对象:

// Rough code - imagine we'd got a wrapper around Dictionary<TKey, TValue>
// to create the pairs automatically.
oddDictionary["key1"] = "value1";
oddDictionary["key2"] = "value2";

var pair1 = oddDictictionary.GetMutablePair("key1");
var pair2 = oddDictictionary.GetMutablePair("key2");
pair1.Key = "key2"; // Overwrite pair2, presumably...
// Does the "changing" remove pair1? Or check for consistency? As it's
// not part of the dictionary before the operation, does this not affect
// the dictionary at all?
pair2.Key = "key3"; 
//粗略的代码-想象一下我们在字典周围有一个包装器
//自动创建对。
oddDictionary[“key1”]=“value1”;
oddDictionary[“key2”]=“value2”;
var pair1=odddictionary.GetMutablePair(“key1”);
var pair2=odddictionary.GetMutablePair(“key2”);
pair1.Key=“key2”//覆盖pair2,大概是。。。
//“更改”是否删除pair1?还是检查一致性?事实上
//操作前不属于字典的一部分,这是否不影响
//那本字典呢?
pair2.Key=“key3”;
基本上,在进一步研究之前,需要仔细考虑很多语义


我建议您为想要实现的行为编写大量的单元测试,然后看看您能做些什么。

为什么需要为
KeyValuePair
实现
INotifyPropertyChanged
?为什么不在
KeyValuePair
中为TKey或TValue实现它?您什么时候需要它?KeyValuePair只有2个属性,它们都是只读的。@最聪明的:TKey是字符串,TValue是对象。除非我按照Jon的建议包装它,否则不要认为我可以为这种原生类型实现它@肯:嗯,我想我也不希望它们是只读的。
ILookup
能帮你什么忙吗?@Jani:ILookup用于一键对多值的dict,不是吗?不是我想要的,两者都有。我也希望关键点是可编辑的。试图允许用户随心所欲地编辑dict。@拉尔夫:在字典中编辑关键字是没有意义的-这意味着从字典中删除以前的条目并添加一个新条目。@Jon:我认为这很有意义。您可能有一个具有string属性的对象,并且可能需要一个由该属性设置键的字典。当该属性更改时,您希望词典自动更新。@Timwi:那么您必须确保每当您创建这样一个词典时,它都会订阅
INotifyPropertyChanged
事件并执行相应的更改。您实际上需要它来订阅
INotifyPropertyChanging
,这样它就可以在密钥更改之前看到更改。。。否则它就不知道要删除哪个条目了。@Jon:我不管它是如何完成的(编辑、删除和重新添加),我只需要那个功能。这就像重命名代码中的变量一样。此外,字典还通过同名的单独属性公开其值和键集合。这些集合分别属于Dictionary.ValueCollection和Dictionary.KeyCollection类型。这些CLR定义的集合不可见。因此,您不能直接绑定到Values集合或Keys集合,并期望收到动态集合更改通知。你必须直接绑定到可观察的字典。”——好吧,这样做是不符合目的的。同意,因为它不是为这个目的设计的。你试过这个代码吗?尝试它没有意义。我需要绑定键和值,而不是整个dict。
// Rough code - imagine we'd got a wrapper around Dictionary<TKey, TValue>
// to create the pairs automatically.
oddDictionary["key1"] = "value1";
oddDictionary["key2"] = "value2";

var pair1 = oddDictictionary.GetMutablePair("key1");
var pair2 = oddDictictionary.GetMutablePair("key2");
pair1.Key = "key2"; // Overwrite pair2, presumably...
// Does the "changing" remove pair1? Or check for consistency? As it's
// not part of the dictionary before the operation, does this not affect
// the dictionary at all?
pair2.Key = "key3";