Вы сформулировали себя не очень похвально, но я рискну предположить, что это то, что вы ищете:
foo = "Hello"
bar = "world"
baz = 2
print "%s, %s number %d" % (foo, bar, baz)
Вы не можете объявить IEnumerable
, потому что тип не имеет (известного) имени во время сборки. Поэтому, если вы хотите использовать этот тип в объявлении функции, сделайте его обычным типом. Или просто измените свой запрос, чтобы он возвращал IENumerable
и придерживайтесь этого типа.
Или верните IEnumerable
с помощью следующего оператора select.
select new KeyValuePair<Int32, String>(id, m.Groups[2].Value)
Я не обязательно рекомендую это ... Это своего рода подрыв системы типов, но вы можете сделать это:
1) измените сигнатуру метода, чтобы вернуть IEnumerable
(не общий)
2) добавьте приведено по примеру helper:
public static class Extensions{
public static IEnumerable<T> CastByExample<T>(
this IEnumerable sequence,
T example) where T: class
{
foreach (Object o in sequence)
yield return o as T;
}
}
3) затем вызовите метод примерно так:
var example = new { Text = "", ItemId = 0, Path = "" };
foreach (var x in SeachItem(ids).CastByExample(example))
{
// now you can access the properties of x
Console.WriteLine("{0},{1},{2}", x.Text, x.ItemId, x.Path);
}
И все готово.
Ключом к этому является тот факт, что если вы создаете анонимный тип с тем же порядком , типы и имена свойств в двух местах, где типы будут использоваться повторно. Зная это, вы можете использовать дженерики, чтобы избежать рефлексии.
Надеюсь, это поможет Алекс
Ваша функция пытается вернуть IEnumerable
Анонимные типы, однако, поскольку они эфемерны до компиляции, могут использоваться только в той области, в которой они созданы. Чтобы удовлетворить ваши потребности в приведенном вами примере, я бы сказал, что самым простым решением является создание простой сущности, которая сохраняет результаты вашего запроса:
public class SearchItemResult
{
public string Text { get; set; }
public int ItemId { get; set; }
public string Path { get; set; }
}
public IEnumerable<SearchItemResult> SearchItem(int[] itemIds)
{
// ...
IEnumerable<SearchItemResult> results = from ... select new SearchItemResult { ... }
}
Однако, если ваша конечная цель не состоит в том, чтобы получить какой-либо объект, а вас интересует только, скажем, Path ... тогда вы все равно можете сгенерировать IEnumerable
IEnumerable<string> lines = from ... select m.Groups[2].Value;
Я надеюсь, что это поможет прояснить ваше понимание LINQ, перечисляемых и анонимных типов. :)
Следует помнить, что операторы LINQ
используют отложенное выполнение . Это означает, что ваш оператор LINQ
фактически не выполняется до тех пор, пока вы не выполните итерацию по нему в операторе foreach
или не вызовете метод .ToList ()
на myLine
.
В вашем примере попробуйте изменить:
return myLine;
Кому:
return myLine.ToList();
Сигнатура метода в SearchItem
указывает, что метод возвращает IEnumerable
, но анонимный тип, объявленный в вашем запросе LINQ, не относится к типу строка
. Если вы хотите сохранить ту же сигнатуру метода, вам нужно изменить свой запрос, чтобы выбрать только строку
seg
return myLine.Select(a => a.Text);
. Если вы настаиваете на возврате данных, выбранных вашим запросом, вы можете вернуть IEnumerable
, если вы замените оператор return
на
return myLine.Cast<object>();
, тогда вы можете использовать объекты с помощью отражения.
Но на самом деле, если вы собираетесь использовать анонимный тип вне метода, который он объявлен в, вы должны определить класс и заставить метод возвращать IEnumerable
этого класса.