Две причины.
Первый, если тот один объект имеет значение, то Ваша очередь всегда полна. Это, вероятно, должно быть больше. Кроме того, если Ваша очередь даже умеренно измерена скажем 1 000 объектов, один объект представляет 0,1% Вашей очереди. Не, что я назвал бы особенно относительно траты памяти.
, Что еще более важно, если Вы не оставляете дополнительный объект, тогда реализация становится чем-то вроде проблемы. Если Вы имеете head
и tail
индексы, то что означает когда head == tail
? Это означает, что очередь полна, или что это пусто? Без большей информации невозможно сказать.
Вы могли поддержать другое значение, которое говорит Вам явно, сколько объектов находится в очереди или просто флаге, чтобы сказать, что это не пусто, но тогда это стоит циклов процессора, чтобы проверить и обновить то значение. И это неэффективно на каждом ставить в очередь или операция двухсторонней очереди.
, Таким образом, Вы хотите потратить впустую циклы процессора на каждую работу с очередями? Или Вы "потратили бы впустую" тривиальный объем памяти для создания кода более простым?
Вы в целом знакомы с делегатами? У меня есть страница о делегатах и событиях , которые могут помочь, если нет, хотя она больше ориентирована на объяснение различий между ними.
Func
- это просто общий делегат - выяснить, что это означает в любой конкретной ситуации, заменив параметры типа ( T
и TResult
) соответствующими аргументами типа ( int
и string
) в объявлении. Я также переименовал его, чтобы избежать путаницы:
string ExpandedFunc(int x)
Другими словами, Func
- это делегат, который представляет функцию, принимающую аргумент int
и возвращающую строка
.
Func
часто используется в LINQ как для проекций, так и для предикатов (в последнем случае TResult
всегда bool
). Например, вы можете использовать Func
для проецирования последовательности целых чисел в последовательность строк. Лямбда-выражения обычно используются в LINQ для создания соответствующих делегатов:
Func<int, string> projection = x => "Value=" + x;
int[] values = { 3, 7, 10 };
var strings = values.Select(projection);
foreach (string s in strings)
{
Console.WriteLine(s);
}
Результат:
Value=3
Value=7
Value=10
A Func
ест целые числа и возвращает строки. Итак, что ест целые числа и возвращает строки? Как насчет этого ...
public string IntAsString( int i )
{
return i.ToString();
}
Я только что придумал функцию, которая ест целые числа и возвращает строки. Как мне это использовать?
var lst = new List<int>() { 1, 2, 3, 4, 5 };
string str = String.Empty;
foreach( int i in lst )
{
str += IntAsString(i);
}
// str will be "12345"
Не очень сексуально, я знаю, но это простая идея, на которой основано множество трюков. Теперь давайте воспользуемся Func.
Func<int, string> fnc = IntAsString;
foreach (int i in lst)
{
str += fnc(i);
}
// str will be "1234512345" assuming we have same str as before
Вместо вызова IntAsString для каждого члена я создал ссылку на него с именем fnc (эти ссылки на методы называются делегатами ) и использовал ее вместо этого. (Помните, что fnc ест целые числа и возвращает строки.)
Этот пример не очень привлекателен, но тонна умных вещей, которые вы увидите, основаны на простой идее функций, делегаты и методы расширения .
Один из лучших учебников по этому вопросу, который я видел, - здесь . У него гораздо больше реальных примеров. :)
Это делегат, который принимает один int
в качестве параметра и возвращает значение типа string
.
Вот пример его использование:
using System;
class Program
{
static void Main()
{
Func<Int32, String> func = bar;
// now I have a delegate which
// I can invoke or pass to other
// methods.
func(1);
}
static String bar(Int32 value)
{
return value.ToString();
}
}