从字典中读取信息



我正在学习字典,在这道题中迷失了方向。

class Program
{
static void Main(string[] args)
{
Dictionary<A, B> dict = new Dictionary<A, B>();
A a = new A { A1 = 1, A2 = 2 };
B b = new B { B1 = 3, B2 = "foo" };
dict.Add(a, b);
A c = new A { A1 = 1, A2 = 2 };
Console.WriteLine($"dict.ContainsKey(a): {dict.ContainsKey(a)}");
Console.WriteLine($"dict.ContainsKey(c): {dict.ContainsKey(c)}");
Console.ReadLine();
}
}
class A
{
public int A1 { get; set; }
public int A2 { get; set; }
}
class B
{
public int B1 { get; set; }
public string  B2 { get; set; }
}

这个代码的输出是:

dict.ContainsKey(a): True
dict.ContainsKey(c): False

我想要实现的是根据参数A1A2得到B2的值。我希望dict.ContainsKey(c)返回true,但由于某种原因它没有。

我可以这样做,它返回foo,但这似乎是多余的?:

(from f in dict.Keys where f.A1==1 && f.A2==2 select dict[f].B2).First()

如果我知道A1A2的值,我如何得到B2的值?

当比较自定义类时,你应该解释。net如何在EqualsGetHashCode方法的帮助下完成它。如果不这样做,.net将比较引用,而不是。在你的例子中,它可以是

class A {
public int A1 { get; set; }
public int A2 { get; set; }
public override bool Equals(object obj) =>
(obj is A other) && (A1 == other.A1) && (A2 == other.A2); 

public override int GetHashCode() => unchecked((A1 << 16) ^ A2); 
// For debugging
public override string ToString() => $"A1 = {A1}; A2 = {A2}";
}

现在

Dictionary<A, B> dict = new Dictionary<A, B>() {
{new A { A1 = 1, A2 = 2 }, new B { B1 = 3, B2 = "foo" }},
};
A c = new A { A1 = 1, A2 = 2 };
if (dict.ContainsKey(c))
Console.WriteLine($"Contains {c}");
else
Console.WriteLine($"Doesn't contains {c}"); 

您需要定义一个类,它实现IEqualityComparer来定义如何比较键。您需要根据它们的属性而不是它们的引用来比较它们。

class AValueComparer : IEqualityComparer<A>
{
public bool Equals(A x, A y) => x.A1 == y.A1 && x.A2 == y.A2;
public int GetHashCode([DisallowNull] A obj) => HashCode.Combine(obj.A1, obj.A2);
}

那么你所需要做的就是把这个比较器和你的字典连接起来。

[Fact]
public void Test1()
{
//Arrange
var dict = new Dictionary<A, B>(new AValueComparer());
var a = new A { A1 = 1, A2 = 2 };
var b = new B { B1 = 3, B2 = "foo" };
dict.Add(a, b);
var c = new A { A1 = 1, A2 = 2 };
//Act
var doesAExist = dict.ContainsKey(a);
var doesCExist = dict.ContainsKey(c);
//Assert
Assert.Equal(doesAExist, doesCExist);
}

这是假的,因为c#中的类是引用类型,而ac具有相同的值(即A1A2是相同的),它们不是相同的实例,这是默认检查的。如果你愿意,你可以实现一个等价于a和它的值的IEqualityComparer,并将它的一个新实例传递给Dictionary构造函数

相关内容

  • 没有找到相关文章

最新更新