private readonly Dictionary<ExcelCellIdentifier, int> allInfoByIdentifier = new Dictionary<ExcelCellIdentifier, int>();
public class ExcelCellIdentifier
{
public ExcelCellIdentifier(string ticker, string identifier)
{
Ticker = ticker;
Identifier = identifier;
}
public string Ticker { get; set; }
public string Identifier { get; set; }
}
然后在某些时候我想通过创建一个具有相同股票代码和标识符的ExcelCellIdentifier对象来搜索int,例如:
ExcelCellIdentifier ex = new ExcelCellIdentifier("Ticker1", "Identifier1");
int a = allInfoByIdentifier[ex];
//a is a value stored before hand
这可能吗?
答案 0 :(得分:3)
Dictionary<TKey, TValue>
需要一个相等的实现来确定密钥是否相等。您可以使用接受 comparer 参数的构造函数指定IEqualityComparer<T>
泛型接口的实现;如果未指定实现,则使用默认的通用相等比较器EqualityComparer<T>.Default
。如果类型 TKey 实现System.IEquatable<T>
通用接口,则默认的相等比较器使用该实现。
由您来决定在这种情况下您希望如何平等 - 在构造字典时提供比较器或实现IEquatable<T>
。中间选项不适合您,因为引用类型的默认比较器使用引用相等。
答案 1 :(得分:1)
是的,只要您在IEquatable<ExcelCellIdentifier>
类中实现ExcelCellIdentifier
,或者使用IEqualityComparer<ExcelCellIdentifier>
实例实例化字典,就可以执行此操作。
要记住的一件重要事情是,虽然我不认为IEquatable<T>
会强制您覆盖GetHashCode()
(即使下面注释了它在文档中的强制要求),您需要确保覆盖它是恰当的,否则即使你的对象对Equals()
返回true,也不能作为在字典中找到另一个的关键。
这是一个很有趣的调试的原因,你确定你的相等比较器工作正常,但不知何故你的字典没有检索任何东西!
为了我的钱,我更喜欢实现自定义的相等比较器,这使得管理字典的业务与您的类的实现分开:
private readonly Dictionary<ExcelCellIdentifier, int> allInfoByIdentifier =
new Dictionary<ExcelCellIdentifier, int>(new ExcelCellIdentifierComparer());
public class ExcelCellIdentifier
{
private ExcelCellIdentifier(string ticker, string identifier)
{
Ticker = ticker;
Identifier = identifier;
}
public string Ticker { get; set; }
public string Identifier { get; set; }
}
private class ExcelCellIdentifierComparer : IEqualityComparer<ExcelCellIdentifier>
{
public bool Equals(ExcelCellIdentifier x, ExcelCellIdentifier y)
{
return x.Identifier == y.Identifier && x.Ticker == y.Ticker;
}
public int GetHashCode(ExcelCellIdentifier obj)
{
return obj.Identifier.GetHashCode() ^ obj.Ticker.GetHashCode();
}
}
答案 2 :(得分:1)
因为没有其他人在这里使用IEquateable给你一个合适的版本你去
public class ExcelCellIdentifier : IEquatable<ExcelCellIdentifier>
{
public ExcelCellIdentifier(string ticker, string identifier)
{
Ticker = ticker;
Identifier = identifier;
}
public override bool Equals(object obj)
{
var identifier = obj as ExcelCellIdentifier;
if(identifier == null)
return false;
else
return Equals(identifier);
}
public override int GetHashCode()
{
//All this below is a common performance thing I add, if you have the two strings "Foo" and "Bar" it will give you a different hash code than the string "Bar" and "Foo", it gives you a better distribution of the hash.
unchecked
{
int hash = 17;
hash = hash * 23 + Ticker.GetHashCode();
hash = hash * 23 + Identifier.GetHashCode();
return hash;
}
}
public string Ticker { get; set; } //This should likely be changed to {get; private set;}
public string Identifier { get; set; } //This should likely be changed to {get; private set;}
public bool Equals(ExcelCellIdentifier other)
{
return Ticker.Equals(other.Ticker) && Identifier.Equals(other.Identifier);
}
}
将这两个方法更改为以下内容以消除对字符串的区分大小写
public override int GetHashCode()
{
//All this below is a common performance thing I add, if you have the two strings "Foo" and "Bar" it will give you a different hash code than the string "Bar" and "Foo", it gives you a better distribution of the hash.
unchecked
{
int hash = 17;
hash = hash * 23 + StringComparer.OrdinalIgnoreCase.GetHashCode(Ticker);
hash = hash * 23 + StringComparer.OrdinalIgnoreCase.GetHashCode(Identifier);
return hash;
}
}
public string Ticker { get; set; } //This should likely be changed to {get; private set;}
public string Identifier { get; set; } //This should likely be changed to {get; private set;}
public bool Equals(ExcelCellIdentifier other)
{
return StringComparer.OrdinalIgnoreCase.Equals(Ticker, other.Ticker) && StringComparer.OrdinalIgnoreCase.Equals(Identifier, other.Identifier);
}
答案 3 :(得分:0)
public class myClass
{
private readonly Dictionary<ExcelCellIdentifier, int> allInfoByIdentifier =
new Dictionary<ExcelCellIdentifier, int>(new ExcelCellIdentifier());
public void testIt()
{
allInfoByIdentifier.Add(new ExcelCellIdentifier("Ticker1", "Identifier1"), 4);
ExcelCellIdentifier ex = new ExcelCellIdentifier("Ticker1", "Identifier1");
int a = allInfoByIdentifier[ex];
}
}
public class ExcelCellIdentifier : IEqualityComparer<ExcelCellIdentifier>
{
public ExcelCellIdentifier()
{
}
public ExcelCellIdentifier(string ticker, string identifier)
{
Ticker = ticker;
Identifier = identifier;
}
public string Ticker { get; set; }
public string Identifier { get; set; }
public bool Equals(ExcelCellIdentifier x, ExcelCellIdentifier y)
{
return x.Identifier == y.Identifier &&
x.Ticker == y.Ticker;
}
public int GetHashCode(ExcelCellIdentifier obj)
{
return obj.Identifier.GetHashCode() ^
obj.Ticker.GetHashCode();
}
}