【问题标题】:How do I provide partial method as an optional Action如何提供部分方法作为可选操作
【发布时间】:2011-06-28 08:17:15
【问题描述】:

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

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

【问题讨论】:

    标签: c# code-generation partial-methods


    【解决方案1】:

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

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

    现在将您的委托绑定到 OnCardTypeVisit 而不是 CardTypeVisit

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

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

    (但是,如果那是一个 表达式 而不是 delegate 我预计会失败)

    【讨论】:

    • 这似乎正是我要找的:return GetLookupItems("ProductCreditCardCardType", x => CardTypeVisit(x));
    • foreach (var item in result) { // 此访问者将执行以下操作: item.Value = "|" +项目.值+“|”;项目访客(项目); LogUtil.Info(item.Value); } foreach (var item in result) { LogUtil.Info(item.Value); } 此代码不更新结果。即在第一个循环中我得到以下(|Visa|、|Mastercard|、|AMEX|),但在第二个循环中我得到(Visa、Mastercard、AMEX)。我会认为 item 是一个引用类型并且会根据 SelectItemList 进行更新,但它似乎是一个副本。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-14
    • 2018-05-17
    • 1970-01-01
    • 2014-11-19
    • 2020-02-12
    • 1970-01-01
    相关资源
    最近更新 更多