1

我正在迁移一些代码并具有格式良好的查找表,但由于向后兼容性,它们必须转换为古老的结构才能使用。

我有一个 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 + "|";
        //}
    }
}

将返回 Select Item List 数据的基本 LookupTable 视图模型

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;
    }
}
4

1 回答 1

1

错误是正确的;如果未实现部分方法,则不存在,因此您不能以这种方式将委托绑定到它们。您最好的选择是基于开关(或类似的)手动调用它,或者如果您确实需要委托,请查找具有反射的方法(记住指定非公共绑定标志)并使用Delegate.CreateDelegateif 方法原来存在。或者一个懒惰的选择:

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

现在将您的代表绑定到OnCardTypeVisit而不是CardTypeVisit.

就委托而言,这也可以像将其更改为间接委托一样简单,这与On*方法非常相似:

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

(但是,如果这是一个表达式而不是一个委托,我会期望失败)

于 2011-06-28T08:22:13.573 回答