(我的回答涉及使用
TrySomething( TInput input, out TOutput value )
方法(如
IDictionary.TryGetValue( TKey, out TValue )
Int32.TryParse( String, out Int32 )
因此它不会直接用OP自己的exmaple代码回答OP的问题。我在这里发布这个答案是因为这个QA是目前Google对“linqtrygetvalue”的最高搜索结果(截至2019年3月)。
1使用C值元组,
System.Tuple
打电话给
TrySomething
方法第一
Select
使用C#7.0值元组(推荐):
// Task: Find and parse only the integers in this input:
IEnumerable<String> input = new[] { "a", "123", "b", "456", ... };
List<Int32> integersInInput = input
.Select( text => Int32.TryParse( text, out Int32 value ) ? ( ok: true, value ) : ( ok: false, default(Int32) ) )
.Where( t => t.ok )
.Select( t => t.value )
.ToList();
这实际上可以通过利用另一个巧妙的技巧来简化
value
.Select
lambda,因此三元表达式变得不必要,如下所示:
// Task: Find and parse only the integers in this input:
IEnumerable<String> input = new[] { "a", "123", "b", "456", ... };
List<Int32> integersInInput = input
.Select( text => ( ok: Int32.TryParse( text, out Int32 value ), value ) ) // much simpler!
.Where( t => t.ok )
.Select( t => t.value )
.ToList();
// Task: Find and parse only the integers in this input:
IEnumerable<String> input = new[] { "a", "123", "b", "456", ... };
List<Int32> integersInInput = input
.Select( text => Int32.TryParse( text, out Int32 value ) ? new { ok = true, value } : new { ok = false, default(Int32) } )
.Where( t => t.ok )
.Select( t => t.value )
.ToList();
使用.NET Framework 4.0
Tuple<T1,T2>
:
// Task: Find and parse only the integers in this input:
IEnumerable<String> input = new[] { "a", "123", "b", "456", ... };
List<Int32> integersInInput = input
.Select( text => Int32.TryParse( text, out Int32 value ) ? Tuple.Create( true, value ) : Tuple.Create( false, default(Int32) ) )
.Where( t => t.Item1 )
.Select( t => t.Item2 )
.ToList();
我写了自己的扩展方法:
SelectWhere
它通过声明自己的
delegate
为具有第二个
out
参数。Linq默认不支持这些,因为
System.Func
外面的
TryFunc
具有
任何
方法,包括
Int32.TryParse
Double.TryParse
,
Dictionary.TryGetValue
支持其他
Try...
具有更多参数的方法,只需定义一个新的委托类型,并为调用方提供指定更多值的方法。
public delegate Boolean TryFunc<T,TOut>( T input, out TOut value );
public static IEnumerable<TOut> SelectWhere<T,TOut>( this IEnumerable<T> source, TryFunc<T,TOut> tryFunc )
{
foreach( T item in source )
{
if( tryFunc( item, out TOut value ) )
{
yield return value;
}
}
}
用法:
// Task: Find and parse only the integers in this input:
IEnumerable<String> input = new[] { "a", "123", "b", "456", ... };
List<Int32> integersInInput = input
.SelectWhere( Int32.TryParse ) // The parse method is passed by-name instead of in a lambda
.ToList();
如果仍要使用lambda,另一种定义使用值元组作为返回类型(需要C#7.0或更高版本):
public static IEnumerable<TOut> SelectWhere<T,TOut>( this IEnumerable<T> source, Func<T,(Boolean,TOut)> func )
{
foreach( T item in source )
{
(Boolean ok, TOut output) = func( item );
if( ok ) yield return output;
}
}
// Task: Find and parse only the integers in this input:
IEnumerable<String> input = new[] { "a", "123", "b", "456", ... };
List<Int32> integersInInput = input
.SelectWhere( text => ( Int32.TryParse( text, out Int32 value ), value ) )
.ToList();
这是因为C#7.0允许在
out Type name