У меня есть следующая функция, использующая выражение лямбда:
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 выбирает тип переменной для создания первой переменной в выражении лямбда?
GetFileNameWithoutExtension
возвращает string
которую вы затем выполняете. .Select
в. Это означает, что вы собираетесь перечислять символы в строке, поскольку строка представляет собой массив символов.
Linq будет смотреть на используемый вами colection и использовать тип внутренних объектов.
Учитывая ваше редактирование, вы можете изменить его на это
Func<string, DateTime> GetDatesFromFileNames
= fileName =>
{
String filenamenoext = Path.GetFileNameWithoutExtension(fileName);
return DateTime.ParseExact(filenamenoext.Substring(filenamenoext.Length - 8, 8), "yyyyMMdd", null));
}
Ну, потому что string
является IEnumerable<char>
и Select
будет работать на char
из string
. Т.е. вы также можете сделать:
foreach(var c in "hello") {
// c is a char
}
Сделайте то, что вы (возможно) хотите просто удалить ненужные LINQ Select
:
Func<string, DateTime> GetDatesFromFileNames = fileName => {
var tmp = Path.GetFileNameWithoutExtension(fileName);
return DateTime.ParseExact(tmp.Substring(tmp.Length - 8, 8), "yyyyMMdd", null);
};
Не похоже, чтобы IEnumerable
возвращался, поскольку у вас, скорее всего, есть только одна дата в имени файла?
s
не будет определен ...
Если я правильно читаю, переходя по возвращаемому значению Func<string, IEnumerable<DateTime>>
вас есть список файлов с прикрепленными датами:
fileA20140101
fileA20140102
fileB20140101
И вам нужно получить некоторый результат, содержащий:
fileA: 01-01-2014
02-01-2014
fileB: 01-01-2014
Однако ваш funtion принимает только одно имя fileName
даже если имя содержит fileNames
. Возможно ли, что string fileName
параметра 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;
DateTime
. Мои извинения, как вы и предлагали ранее, я пытался реорганизовать его так, чтобы он работал только на одной string
и возвращал один DateTime
. Я редактировал вопрос
.Select
тогда. Есть ли более подходящая опция, которая позволяет мне работать со всей строкой?