Как предоставить частичный метод в качестве необязательного действия - PullRequest
1 голос
/ 28 июня 2011

Я мигрирую некоторый код и красиво отформатировал справочные таблицы, но их необходимо преобразовать в архаичные структуры для использования из-за обратной совместимости.

У меня есть метод GetLookupTable (), который идет и получаетсписок SelectItemList, все мои модели и вызовы поиска генерируются кодом, но мне нужно вручную изменить некоторые из возвращаемых SelectItem, чтобы я реализовал шаблон посетителя, который разработчик может реализовать, если они пожелают.

Посетительсделано как частичный метод, и если разработчик хочет реализовать, они могут, но я получаю ошибку, как показано ниже

Ошибка 132 Не удается создать делегат из метода 'InfoChoice.Web.Admin.ViewModels.Product.ProductCreditCardViewModel.LookupTableViewModel.CardTypeVisit (System.Web.Mvc.SelectListItem) ', поскольку это частичный метод без реализующего объявления

Вот код вызова с использованием Razor

<div class='row'>
    <label>Card Type</label>
    @Html.CheckBoxListFor(model => model.CardType, @Model.LookupTable.CardType)
    David Says: @Model.CardType
</div>

Вот урезанная модель

// Generated model
public partial class ProductCreditCardViewModel
{
    [Required]
    [DisplayName("Account - Card Type")]
    [DefaultValue("")]
    public string CardType { get; set; }


    // ***************************************************************************************************
    // Lookup Table calls for this model (Generated)
    // ***************************************************************************************************
    public partial class LookupTableViewModel : BaseLookupTableViewModel
    {
        partial void CardTypeVisit(SelectListItem item);

        public SelectList CardType
        {
            get
            {
                return GetLookupItems("ProductCreditCardCardType", CardTypeVisit);
            }
        }
    }

}

public partial class ProductCreditCardViewModel
{
    // Custom Implementation Goes Here
    public partial class LookupTableViewModel : BaseLookupTableViewModel
    {
        //partial void CardTypeVisit(SelectListItem item)
        //{
        //    item.Value = "|" + item.Value + "|";
        //}
    }
}

База LookuМодель представления таблицы pTable, которая возвращает данные списка элементов данных

public class BaseLookupTableViewModel
{
    public SelectList GetLookupItems(string lookupName)
    {
        return GetLookupItems(lookupName, "Name", "Text", null, null);
    }
    public SelectList GetLookupItems(string lookupName, Action<SelectListItem> itemVisitor)
    {
        return GetLookupItems(lookupName, "Name", "Text", null, itemVisitor);
    }
    public SelectList GetLookupItems(string lookupName, string dataValueField, string dataTextField, object selectedValue, Action<SelectListItem> itemVisitor)
    {
        // Go get some data from DataStore
        var list = App.Data.Lookup.GetLookupList(lookupName);

        // Convert to IEnumerable<SelectItemList>
        var result = new SelectList(list, dataValueField, dataTextField, selectedValue);

        // If developer would like to alter that list before it is returned, then developer should implement an item visitor
        if (itemVisitor != null)
        {
            foreach (var item in result)
            {
                itemVisitor(item);
            }
        }

        return result;
    }

    public void SampleVisitor(SelectListItem item)
    {
        item.Value = "Modified: " + item.Value;
    }
}

1 Ответ

1 голос
/ 28 июня 2011

ошибка правильная;частичные методы не существуют , если они не реализованы, поэтому вы не можете привязать к ним делегата таким способом.Ваш лучший вариант здесь - либо вызвать его вручную, возможно, с помощью переключателя (или аналогичного), либо, если вам действительно нужен делегат, ищите метод с отражением (не забудьте указатьнепубличные флаги привязки) и используйте Delegate.CreateDelegate, если метод оказывается существующим.Или ленивый вариант:

private void OnCardTypeVisit(SelectListItem item) { CardTypeVisit(item); }
partial void CardTypeVisit(SelectListItem item);

теперь привязывайте вашего делегата к OnCardTypeVisit вместо CardTypeVisit.

С точки зрения делегатов это также может быть так же просто, как изменить егокосвенный делегат, который очень похож на подход On*:

return GetLookupItems("ProductCreditCardCardType", x => CardTypeVisit(x));

(однако, если это выражение , а не делегат , я бы ожидалотказ)

...