C#: Сортировка с анонимной функцией

Ошибка означает, что значение CategoryList равно нулю (и в результате метод DropDownListFor() ожидает, что первый параметр имеет тип IEnumerable).

Вы не генерируете вход для каждого свойства каждого SelectListItem в CategoryList (и не должен), поэтому никакие значения для SelectList не отправляются в метод контроллера, и поэтому значение model.CategoryList в методе POST равно null , Если вы вернете представление, вы должны сначала переназначить значение CategoryList, как и в методе GET.

public ActionResult Create(ProjectVM model)
{
    if (!ModelState.IsValid)
    {
        model.CategoryList = new SelectList(db.Categories, "ID", "Name"); // add this
        return View(model);
    }
    // Save and redirect
}

Чтобы объяснить внутреннюю работу (исходный код может быть см. здесь )

Каждая перегрузка DropDownList() и DropDownListFor() в конечном итоге вызывает следующий метод

private static MvcHtmlString SelectInternal(this HtmlHelper htmlHelper, ModelMetadata metadata,
  string optionLabel, string name, IEnumerable selectList, bool allowMultiple,
  IDictionary htmlAttributes)

, который проверяет, есть ли selectList (второй параметр из @Html.DropDownListFor()) является null

// If we got a null selectList, try to use ViewData to get the list of items.
if (selectList == null)
{
    selectList = htmlHelper.GetSelectData(name);
    usedViewData = true;
}

, который, в свою очередь, вызывает

private static IEnumerable GetSelectData(this HtmlHelper htmlHelper, string name)

, который оценивает первый параметр @Html.DropDownListFor() (в данном случае CategoryID )

....
o = htmlHelper.ViewData.Eval(name);
....
IEnumerable selectList = o as IEnumerable;
if (selectList == null)
{
    throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture, 
        MvcResources.HtmlHelper_WrongSelectDataType,
        name, o.GetType().FullName, "IEnumerable"));
}

Поскольку свойство CategoryID является typeof int, оно не может быть передано в IEnumerable, и генерируется исключение (которое определено в файле MvcResources.resx как)


    The ViewData item that has the key '{0}' is of type '{1}' but must be of type '{2}'.

24
задан Skurmedel 23 January 2010 в 03:51
поделиться

4 ответа

Почему бы не использовать выражение лямбда?

public string SortByDateModified(List<CartItem> items) 
{ 
    items.Sort((a, b) => a.DateModified.CompareTo(b.DateModified)); 
} 
53
ответ дан 28 November 2019 в 22:21
поделиться

bool бесполезен для такого делегата, обычно используется int, потому что вам нужно 3 значения для представления результатов сравнения, меньше, равно и больше, чем. Коллекции .NET обычно (если не всегда) предполагают, что -1 означает меньше чем, 0 означает равный и 1 означает больше чем.

Затем вы должны в своем делегате проверить, является ли значение x меньше, равно или больше значения y. Интересно отметить, что если вы перевернете результаты, например, сравните y с x, то вы будете сортировать в противоположном направлении.

Чтобы упростить сортировку дат, проверьте ответ Джона Си или Сэма .

0
ответ дан Community 16 October 2019 в 07:46
поделиться

Если вы не хотите использовать лямбдас или больше, чем .NET 2.0, используйте это:

public string SortByDateModified(List<CartItem> items) 
{ 
    items.Sort(delegate(CartItem itemA, CartItem itemB) 
    { 
        return itemA.DateModified.CompareTo(itemB.DateModified); 
    }); 
} 

в моем опыте, в средах, таких как единство, лямбдас и даже делегаты могут вызвать сбои или проблемы, особенно на платформах, таких как iOS Отказ В этом случае вы хотели бы сделать вашу сортировку отдельную функцию, например:

int SortCartItemFunction(CartItem itemA, CartItem itemB) 
{ 
    return itemA.DateModified.CompareTo(itemB.DateModified); 
} 

, то вы можете передать его на ваш сорт, как это:

items.Sort(SortCartItemFunction);
15
ответ дан 28 November 2019 в 22:21
поделиться

Метод

Сортировка принимает задачу называемого сравнение . Вы пытаетесь пройти в ФУНК , который сам по себе является делегатом. Нет преобразования между делегатом FUNC и делегатом сравнение .

Вы можете, однако, использовать лямбда лямбда .

items.Sort((a, b) => a.DateModified.CompareTo(b.DateModified));

Действительно, вы используете это очень лямбда экспрессию и пропустите его в функцию конструктор *. Однако нет необходимости. Выражение лямбда может быть преобразовано в любой делегат подписи для подписи - то есть (a, b) => aTedemodified.compareeto (b.datemodificed) может быть назначен на что-то набранное func , int, int> или что-то набранное сравнение . В этом случае мы передаем его на что-то, что ожидает сравнения .

* с одной незначительной корректировкой. Сортировать ожидает целое число в качестве типа возврата. Отрицательные значения указывают на меньшее, чем 0 указывает на равные, а положительные значения указывают больше, чем.

11
ответ дан 28 November 2019 в 22:21
поделиться
Другие вопросы по тегам:

Похожие вопросы: