.NET 结合 Exists() 和 First()
.NET Combining Exists() with First()
现在,我有以下代码:
List<MyType> objectList = MyType.GetList();
MyType objectInstance = new MyType();
if (objectList.Exists(o => o.MyProperty == "SomeValue"))
{
objectInstance = objectList.First(o => o.MyProperty == "SomeValue"));
DoStuff();
}
else if (objectList.Exists(o => o.MyProperty == "SomeOtherValue"))
{
objectInstance = objectList.First(o => o.MyProperty == "SomeOtherValue"));
DoStuff();
}
有什么方法可以避免先进行 Exists 检查,然后进行赋值?
我知道我可以使用FirstOrDefault代替,如下:
List<MyType> objectList = MyType.GetList();
MyType objectInstance = new MyType();
objectInstance = objectList.FirstOrDefault(o => o.MyProperty == "SomeValue"));
if (objectInstance != null)
DoStuff();
else
{
objectInstance = objectList.FirstOrDefault(o => o.MyProperty == "SomeValue"));
if (objectInstance != null)
DoStuff();
}
但这似乎并没有更有效。
我希望能够实现类似于 TryParse() 的行为。我知道我可以为此编写自己的包装器,如果没有内置的方法,我会这样做,但我想在我做之前先检查一下。基本上,我想要的是:
List<MyType> objectList = MyType.GetList();
MyType objectInstance = new MyType();
if (objectList.TryFirst(o => o.MyProperty == "SomeValue", out objectInstance))
DoStuff();
else if (objectList.TryFirst(o => o.MyProperty == "SomeOtherValue", out objectInstance))
DoStuff();
只需通过第一个元素的 属性 创建查找:
var lookup = objectList.GroupBy(x=> x.MyProperty).ToDictionary(x=> x.MyProperty, x=> x.First());
if(lookup.TryGetValue("SomeValue", out objectInstance) || lookup.TryGetValue("SomeOtherValue", out objectInstance))
{
DoStuff();
}
您是否正在尝试缩短源代码行数?好的,你可以做类似的事情(但是因为排序会慢一点):
var objectInstance = objectList.OrderByDescending(o => o.MyProperty == "SomeValue").ThenByDescending(o => o.MyProperty == "SomeOtherValue").FirstOrDefault();
if (objectInstance.MyProperty == "SomeValue" || objectInstance.MyProperty == "SomeOtherValue")
{
DoStuff();
}
如果您需要找到满足条件的序列中的第一个元素,您也可以在排序前select索引。
var objectInstance =
objectList.FirstOrDefault(o => o.MyProperty == "SomeValue")) ??
objectList.FirstOrDefault(o => o.MyProperty == "SomeOtherValue"));
if (objectInstance != null) DoStuff();
FirstOrDefault 是 TryParse 等价物。当您有单独的存在并首先检查时,这将导致集合被迭代两次。对于非常大的列表或由生成函数支持的 IEnumerables(例如从 SqlDataReader 生成结果),这可能会非常昂贵。
现在,我有以下代码:
List<MyType> objectList = MyType.GetList();
MyType objectInstance = new MyType();
if (objectList.Exists(o => o.MyProperty == "SomeValue"))
{
objectInstance = objectList.First(o => o.MyProperty == "SomeValue"));
DoStuff();
}
else if (objectList.Exists(o => o.MyProperty == "SomeOtherValue"))
{
objectInstance = objectList.First(o => o.MyProperty == "SomeOtherValue"));
DoStuff();
}
有什么方法可以避免先进行 Exists 检查,然后进行赋值?
我知道我可以使用FirstOrDefault代替,如下:
List<MyType> objectList = MyType.GetList();
MyType objectInstance = new MyType();
objectInstance = objectList.FirstOrDefault(o => o.MyProperty == "SomeValue"));
if (objectInstance != null)
DoStuff();
else
{
objectInstance = objectList.FirstOrDefault(o => o.MyProperty == "SomeValue"));
if (objectInstance != null)
DoStuff();
}
但这似乎并没有更有效。
我希望能够实现类似于 TryParse() 的行为。我知道我可以为此编写自己的包装器,如果没有内置的方法,我会这样做,但我想在我做之前先检查一下。基本上,我想要的是:
List<MyType> objectList = MyType.GetList();
MyType objectInstance = new MyType();
if (objectList.TryFirst(o => o.MyProperty == "SomeValue", out objectInstance))
DoStuff();
else if (objectList.TryFirst(o => o.MyProperty == "SomeOtherValue", out objectInstance))
DoStuff();
只需通过第一个元素的 属性 创建查找:
var lookup = objectList.GroupBy(x=> x.MyProperty).ToDictionary(x=> x.MyProperty, x=> x.First());
if(lookup.TryGetValue("SomeValue", out objectInstance) || lookup.TryGetValue("SomeOtherValue", out objectInstance))
{
DoStuff();
}
您是否正在尝试缩短源代码行数?好的,你可以做类似的事情(但是因为排序会慢一点):
var objectInstance = objectList.OrderByDescending(o => o.MyProperty == "SomeValue").ThenByDescending(o => o.MyProperty == "SomeOtherValue").FirstOrDefault();
if (objectInstance.MyProperty == "SomeValue" || objectInstance.MyProperty == "SomeOtherValue")
{
DoStuff();
}
如果您需要找到满足条件的序列中的第一个元素,您也可以在排序前select索引。
var objectInstance =
objectList.FirstOrDefault(o => o.MyProperty == "SomeValue")) ??
objectList.FirstOrDefault(o => o.MyProperty == "SomeOtherValue"));
if (objectInstance != null) DoStuff();
FirstOrDefault 是 TryParse 等价物。当您有单独的存在并首先检查时,这将导致集合被迭代两次。对于非常大的列表或由生成函数支持的 IEnumerables(例如从 SqlDataReader 生成结果),这可能会非常昂贵。