如何为动态类型创建 MVC 扩展方法

How to create MVC Extension Method for Dynamic type

我想为动态类型创建扩展方法,但由于某些或其他原因,我在编译代码时出错。下面是我的代码示例 我使用的方法是

public List<State> getStates()
{

    return new List<State>(){
         new State{StateID="1",StateName="Tamil Nadu"},
         new State{StateID="2",StateName="Assam"},
         new State{StateID="3",StateName="Andra"},
         new State{StateID="4",StateName="bihar"},
         new State{StateID="5",StateName="Bengal"},            
    };
}

我的扩展方法是

public static class helper
{
     public static IEnumerable<SelectListItem> getIntoDropDownState(this List<dynamic> data,string textField,string valueField)
    {
        return data.Select(x => new SelectListItem
        {
            Text = x.textField,
            Value = x.valueField
        });
    }
}

我得到的编译错误是

Compiler Error Message: CS1928: 'System.Collections.Generic.List' does not contain a definition for 'getIntoDropDownState' and the best extension method overload 'LearnAuthentication.Controllers.helper.getIntoDropDownState(System.Collections.Generic.List, string, string)' has some invalid arguments

我想像这样使用扩展方法,但遇到错误

 @Html.DropDownListFor(x => x.StateID, new LearnAuthentication.Controllers.Address().getStates().getIntoDropDownState("StateName", "StateID"), "Select State", 0)

谁能帮忙

不支持扩展方法中的动态类型。 将动态类型转换为实际类型,它将起作用。 有关详细信息,请查看以下内容 URL, Extension methods cannot be dynamically dispatched

您示例中的扩展方法不会执行您描述的操作。您可以使用反射和泛型。

public static class helper {
    public static IEnumerable<SelectListItem> getIntoDropDownState<T>(this List<T> data, string textField, string valueField) where T : class {
        var type = typeof(T);

        var textPropertyInfo = type.GetProperty(textField);
        var valuePropertyInfo = type.GetProperty(valueField);

        return data.Select(x => new SelectListItem {
            Text = (string)textPropertyInfo.GetValue(x),
            Value = (string)valuePropertyInfo.GetValue(x)
        });
    }
}

这是扩展方法的单元测试

[TestClass]
public class MyTestClass {
    [TestMethod]
    public void MyTestMethod() {
        //Arrange
        var data = getStates();

        //Act
        var result = data.getIntoDropDownState("StateName", "StateID");

        //Assert
        Assert.IsNotNull(result);
        var first = result.First();
        Assert.AreEqual(data[0].StateName, first.Text);
        Assert.AreEqual(data[0].StateID, first.Value);
    }

    public List<State> getStates() {

        return new List<State>(){
             new State{StateID="1",StateName="Tamil Nadu"},
             new State{StateID="2",StateName="Assam"},
             new State{StateID="3",StateName="Andra"},
             new State{StateID="4",StateName="bihar"},
             new State{StateID="5",StateName="Bengal"},            
        };
    }

    public class State {
        public string StateID { get; set; }
        public string StateName { get; set; }
    }
}

或者您可以放弃反射并使用 System.Web.Mvc.SelectList 来为您完成大量的反射提升

public static class helper {
    public static IEnumerable<System.Web.Mvc.SelectListItem> getIntoDropDownState<T>(this List<T> data, string textField, string valueField) where T : class {

        return new System.Web.Mvc.SelectList(data, valueField, textField);

    }
}