我使用lambda表达式有以下函数:
Func<string, DateTime> GetDateFromFileName
= fileName => Path.GetFileNameWithoutExtension(fileName)
.Select(s => DateTime.ParseExact(s.Substring(s.Length - 8, 8), "yyyyMMdd", null));
但是编译器抱怨char
没有.Length
或.Substring()
。为什么决定s
是char
而不是string
?有没有更优雅的方式来完成上述工作,而不是投入几个.ToString()
s?
Func<string, DateTime> GetDateFromFileName
= fileName => Path.GetFileNameWithoutExtension(fileName)
.Select(s => DateTime.ParseExact(s.ToString().Substring(s.ToString().Length - 8, 8), "yyyyMMdd", null));
linq如何选择在lambda表达式中创建第一个变量的变量类型?
答案 0 :(得分:5)
GetFileNameWithoutExtension
会返回string
,您正在进行.Select
。这意味着您将枚举字符串中的字符,因为字符串是char数组。
Linq将查看您正在使用的集合并使用内部对象的类型。
鉴于您的编辑,您可以将其更改为此
Func<string, DateTime> GetDatesFromFileNames
= fileName =>
{
String filenamenoext = Path.GetFileNameWithoutExtension(fileName);
return DateTime.ParseExact(filenamenoext.Substring(filenamenoext.Length - 8, 8), "yyyyMMdd", null));
}
答案 1 :(得分:3)
好吧,因为string
是IEnumerable<char>
而Select
将在char
的{{1}}上运行。即你也可以这样做:
string
做你想做的事情(可能)只需删除不必要的LINQ foreach(var c in "hello") {
// c is a char
}
:
Select
因为你很可能只有一个日期的文件名,所以让Func<string, DateTime> GetDatesFromFileNames = fileName => {
var tmp = Path.GetFileNameWithoutExtension(fileName);
return DateTime.ParseExact(tmp.Substring(tmp.Length - 8, 8), "yyyyMMdd", null);
};
作为回报真的没有任何意义吗?
答案 2 :(得分:1)
如果我正确阅读,请按Func<string, IEnumerable<DateTime>>
的返回值列出一些附有日期的文件列表:
fileA20140101
fileA20140102
fileB20140101
你需要得到一些结果:
fileA: 01-01-2014
02-01-2014
fileB: 01-01-2014
但是,即使名称包含fileName
,您的功能也只需要一个fileNames
。参数string fileName
可能需要IEnumerable<string> fileNames
吗?这可能会更有意义地查看函数的实现!
根据评论进行更新
因此,您的函数只返回一个日期时间。
static DateTime GetDateFromFileName(string fileName) {
const string format = "yyyMMdd";
string withoutExtension = Path.GetFileNameWithoutExtension(fileName);
return DateTime.ParseExact(
withoutExtension.Substring(withoutExtension.Length - format.Length),
format, null);
}
Func<string, DateTime> myFunc = GetDateFromFileName;