C# 字典使用对象作为键。密钥在字典之外更新

C# 字典使用对象作为键。密钥在字典之外更新,c#,C#,考虑一个简单的类: public class TestClass<Val> { public Val Value{get;set;} } 现在,字典如下所示:{TestCase->Value=0:10} 现在,请执行以下操作: TestCase.Value=1 现在,我在字典中自动添加了{TestCase->Value=1:10},而没有将键'TestCase->Value=1'放入字典。我怎样才能避免它呢?实际上TestClass只有一个实例。您在dictionary之

考虑一个简单的类:

public class TestClass<Val>
{
    public Val Value{get;set;}
}
现在,字典如下所示:{TestCase->Value=0:10} 现在,请执行以下操作:

TestCase.Value=1

现在,我在字典中自动添加了{TestCase->Value=1:10},而没有将键'TestCase->Value=1'放入字典。我怎样才能避免它呢?

实际上TestClass只有一个实例。您在dictionary之外创建了它,然后将该实例添加到dictionary

若您对实例进行更改,它将反映在字典中。这是肤浅的模仿


要避免此问题,请创建实例的deepclone,然后创建外接程序字典。在这种情况下,一个实例中的更改不会反映在另一个实例中。

实际上,TestClass只有一个实例。您在dictionary之外创建了它,然后将该实例添加到dictionary

若您对实例进行更改,它将反映在字典中。这是肤浅的模仿


要避免此问题,请创建实例的deepclone,然后创建外接程序字典。在这种情况下,一个类型中的更改不会反映在另一个中。

基本上,不要使用可变类型作为键。。。或者,如果你这样做了,确保你从来没有变异的关键。第一个更好

一个更大的问题是,如果TestClass有一个定制的GetHashCode/Equals实现,您可以完全破坏字典,因为它可能不再能够找到该键的值,即使您给它一个您开始使用的确切实例


理想情况下,用作键的任何内容都应该是不可变的。出于这个原因,int和string是很好的选择,但您也可以按照@lazyberezovsky的例子,使您的类型不可变。

基本上,不要将可变类型用作键。。。或者,如果你这样做了,确保你从来没有变异的关键。第一个更好

一个更大的问题是,如果TestClass有一个定制的GetHashCode/Equals实现,您可以完全破坏字典,因为它可能不再能够找到该键的值,即使您给它一个您开始使用的确切实例

理想情况下,用作键的任何内容都应该是不可变的。因此,int和string是很好的选择,但您也可以按照@lazyberezovsky的示例,使您的类型不可变。

创建不可变的TestCase类:

创建不可变的TestCase类:


如果你想在字典中使用Equals和,记得在你的类中实现它。@Tim实际上,目前这只是一个表面问题;如果在此基础上实现Equals/GetHashCode,它可能会成为一个功能性很强的问题,破坏字典。我同意它应该有这些方法,但理想情况下,只能在使键类型不可变的同时应用这些方法。如果您想将其用作字典中的键,请记住在类中实现Equals和。@Tim实际上,目前这只是一个表面问题;如果在此基础上实现Equals/GetHashCode,它可能会成为一个功能性很强的问题,破坏字典。我同意它应该有那些方法,但理想情况下,这只能在使键类型不可变的同时应用。但在这种情况下,我不能使用TestCase.Value=0,并且每次都需要像TestCase=new TestCase一样创建TestCase。如果循环足够大,是否可以?您不能在字典中为不同的键使用一个对象-无论如何,您需要创建新的keys但是在这种情况下,我不能使用TestCase.Value=0,并且需要再次创建TestCase,就像TestCase=new TestCase0一样,如果循环足够大,是否可以?在字典中不能对不同的键使用一个对象-无论如何,如果我错了,你需要创建新的keys来纠正我,我需要在TestClass类中创建一个方法DeepCopy,如下所述,在这里我使用MemberCloneWise并将类成员复制到一个新类。您认为制作深度复制或按照@lazyberezovsky的建议创建新实例更快的方法是什么?请纠正我的错误,我需要在TestClass类中创建一个方法DeepCopy,如这里所述,在这里我使用MemberCloneWise并将类成员复制到一个新类。正如@lazyberezovsky所建议的那样,您认为制作深度副本或创建新实例的速度更快吗?正如您所说,我面临的下一个问题是,给定同一个实例时,不可能找到该键的值,因此我必须向类中添加Equals和GetHashCode,正如您所说,我面临的下一个问题是,在给定同一个实例的情况下,不可能找到该键的值,因此我必须将Equals和GetHashCode添加到类中
TestCase.Value=0
D.Add(TestCase,10)
TestCase.Value=1
public class TestClass<Val>
{
    public TestClass(Val value)
    {
       Value = value;
    }

    public Val Value{ get; private set; }
}