为了使用 Contains 方法,更好的是(有什么区别),用 HashSet 声明一个静态字段或将其声明为内联 (new HashSet { SomeEnum.SomeValue1, SomeEnum.SomeValue2, ... }.Contains(SomeEnum .SomeValue1))
我这么问是因为在某些情况下我只会使用一次哈希集,对我来说最好将它放在代码中而不是某些静态属性中
内联示例(我想使用的):
public void Validate(Type type) {
if(!new HashSet<Type> { Type.TYPE_1, Type.TYPE_2, Type.TYPE_3, Type.TYPE_4 }.Contains(type)) {
//do something
}
if(new HashSet<Type> { Type.TYPE_2, Type.TYPE_3, Type.TYPE_4, Type.TYPE_5 }.Contains(type)) {
//do something
}
}
静态示例(我不喜欢使用):
private static HashSet<Type> _values1 = new HashSet<Type> { Type.TYPE_1, Type.TYPE_2, Type.TYPE_3, Type.TYPE_4 };
private static HashSet<Type> _values2 = new HashSet<Type> { Type.TYPE_2, Type.TYPE_3, Type.TYPE_4, Type.TYPE_5 };
public void Validate(Type type) {
if(!_values1.Contains(type)) {
//do something
}
if(_values2.Contains(type)) {
//do something
}
}
使用逻辑表达式的示例(我不想使用的):
public void Validate(Type type) {
if(type != Type.TYPE_1 && type != Type.TYPE_2 && type != Type.TYPE_3 && type != Type.TYPE_4) {
//do something
}
if(type == Type.TYPE_2 || type == Type.TYPE_3 || type == Type.TYPE_4 || type == Type.TYPE_5) {
//do something
}
}
最佳答案
如果您没有通过性能测试将其识别为瓶颈,那么“正确”的方法就是使用对阅读它的人来说最有意义的代码。这有点主观,所以可能没有“正确”的方法,但任何不容易理解的方法都将是“错误”的方法。
我可能只会使用内联声明的数组,除非值列表可以在其他方法中重用,或者它太长以至于妨碍读取该方法正在尝试执行的操作。
public void Validate(Type type) {
if(!new[] { Type.TYPE_1, Type.TYPE_2, Type.TYPE_3, Type.TYPE_4 }.Contains(type)) {
//do something
}
}
如果您已将其确定为明确的性能瓶颈(意味着您可能每秒执行数百万次此检查,那么您可能需要对几种不同的方法进行性能测试,因为正确的答案取决于您尝试匹配的集合中有多少项。
除了您建议的方法之外,这里还有一些其他可能可能更快的方法(但同样,您需要测试它们以确保:
标志枚举
看起来您正在使用枚举值。如果该枚举类型具有少量潜在值,您可以将其放入标志枚举中,然后使用按位逻辑在单个 CPU 操作中确定给定值是否与您正在查找的任何值相匹配。
[Flags]
public enum Type
{
TYPE_1 = 1,
TYPE_2 = 1<<1,
TYPE_3 = 1<<2,
TYPE_4 = 1<<3,
TYPE_5 = 1<<4,
// etc...
}
用法:
const Type toMatch = (Type.TYPE_1 | Type.TYPE_2 | Type.TYPE_3 | Type.TYPE_4);
if((type & toMatch) == 0)
{
// do something
}
Switch 语句
编译器非常擅长找出最快的方法,因此如果您使用 switch 语句,它可以决定是否将其编译为一系列 if/else 检查、HashSet 样式的方法或跳转表,具体取决于您要检查的项目的数量和值。
switch(type)
{
case Type.TYPE_1:
case Type.TYPE_2:
case Type.TYPE_3:
case Type.TYPE_4:
break;
default:
// do something
break;
}
关于c# - 内联 HashSet<> 声明与静态属性,.Contains() 性能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19796109/