优雅的C#方法返回一个IEnumerable<;T>;从布尔TryParse<;T>;(Input,ou
本文关键字:gt lt 布尔 ou Input TryParse IEnumerable 方法 返回 一个 | 更新日期: 2023-09-27 18:20:10
有没有一种从构建IEnumerable<T>
的优雅方法
bool TryParse<T>(Input, out T)
和类型的输入
Input[,]
基本上,我有一个Input的2D数组,并希望在每个Input上调用TryParse,如果TryParse<T>
返回true,我将把'out'中的返回值附加到IEnumerable<T>
中。
我可以在for循环中轻松做到这一点,但我想要更优雅的。这就是我现在使用的:
var marketInputColl = new Collection<MarketInput>();
foreach (object o in marketInputs)
{
MarketInput mktInput;
if (ExcelCache.TryGetCache<MarketInput>(o.ToString(), out mktInput))
marketInputColl.Add(mktInput);
}
out/ref参数在LINQ中并不能很好地发挥作用。你可以做,但很乱。优选的选项是使用解析工具,该工具将返回可为null的int(如果无法解析值,则使用null),而不是使用out
:
public static int? TryParse(string s)
{
int output;
if (int.TryParse(s, out output))
return output;
else
return null;
}
只要不需要存储实际null
值,就可以为从缓存中获取值的尝试创建一个可比较的函数。
这允许你写:
var query = data.Select(item => TryGetCache(item.ToString()))
.Where(n => n != null);
您可以用一种通用的方式来完成:
static class Extensions
{
public delegate bool TryParseDelegate<TSource>(string s, out TSource source);
public static IEnumerable<TResult> WhereParsed<TSource, TResult>(
this IEnumerable<TSource> source,
TryParseDelegate<TResult> tryParse)
{
// check arguments against null first
foreach (var item in source)
{
TResult result;
if (tryParse(item.ToString(), out result))
{
yield return result;
}
}
}
}
用法:
var result = marketInputs.Cast<object>()
.WhereParsed<object, MarketInput>
// need to specify explicit,
// out param type cannot be inferred from usage
(ExcelCache.TryGetCache).ToList();
TryParse()
的问题在于它不是任何接口的实现:您要么需要使用反射来找到方法,要么(更简单)只提供一个转换委托。
然后你可以做这样的事情,使用2D阵列(或者实际上,任何维度的阵列:
string[,] raw = { { "1" , "2" , } ,
{ "3" , "X" , } ,
{ "5" , "6" , } ,
} ;
int?[] converted = raw.Cast<string>()
.Select( s => {
int value ;
bool parsed = int.TryParse( s , out value ) ;
return parsed ? (int?) value : (int?)null ;
})
.ToArray()
;
如果你的阵列是锯齿状的,你还需要一个步骤:
string[][] raw = { new string[]{"1","2",} ,
new string[]{"3","X",} ,
new string[]{"5","6",} ,
} ;
int?[] converted = raw.Cast<string[]>()
.SelectMany( s => s )
.Select( s => {
int value ;
bool parsed = int.TryParse( s , out value ) ;
return parsed ? (int?) value : (int?)null ;
})
.ToArray()
;
举个例子:
var marketInputColl = new Collection<MarketInput>();
foreach (object o in marketInputs)
{
MarketInput mktInput;
if (ExcelCache.TryGetCache<MarketInput>(o.ToString(), out mktInput))
marketInputColl.Add(mktInput);
}
我们可以采取相同的基本方法:
Collection<MarketInput> collection = new Collection<MarketInput>(
marketInputs
.Cast<object>()
.Select( o => o.ToString() )
.Select( s => {
MarketInput v ;
bool parsed = ExcelCache.TryGetCache<MarketInput>( s , out v ) ;
return parsed ? v : null ;
})
.Where( x => x != null )
.ToList()
) ;