将强类型属性名称作为参数传递

bfl*_*mi3 3 c# lambda strong-typing

我有一个IEnumerable<School>正在传递给一个扩展方法的集合,该方法填充DropDownList. 我也想将DataValueFieldandDataTextField作为参数传递, 但我希望它们是强类型的。

基本上,我不想stringDataValueFieldDataTextField参数传递 a ,这很容易出错。

public static void populateDropDownList<T>(this DropDownList source,
        IEnumerable<T> dataSource,
        Func<T, string> dataValueField,
        Func<T, string> dataTextField) {
    source.DataValueField = dataValueField; //<-- this is wrong
    source.DataTextField = dataTextField; //<-- this is wrong
    source.DataSource = dataSource;
    source.DataBind();
}
Run Code Online (Sandbox Code Playgroud)

这么叫...

myDropDownList.populateDropDownList(states,
        school => school.stateCode,
        school => school.stateName);
Run Code Online (Sandbox Code Playgroud)

我的问题是,我怎么能传递DataValueFieldDataTextField强类型作为参数传递给populateDropDownList?

bfl*_*mi3 5

基于乔恩的回答和这篇文章,它给了我一个想法。我通过了DataValueFieldDataTextField作为Expression<Func<TObject, TProperty>>我的扩展方法。我创建了一个接受该表达式并返回该MemberInfo属性的方法。然后我只需要打电话.Name,我就有了我的string.

哦,我把扩展方法名改成了populate,太丑了。

public static void populate<TObject, TProperty>(
        this DropDownList source, 
        IEnumerable<TObject> dataSource, 
        Expression<Func<TObject, TProperty>> dataValueField, 
        Expression<Func<TObject, TProperty>> dataTextField) {
    source.DataValueField = getMemberInfo(dataValueField).Name;
    source.DataTextField = getMemberInfo(dataTextField).Name;
    source.DataSource = dataSource;
    source.DataBind();
}

private static MemberInfo getMemberInfo<TObject, TProperty>(Expression<Func<TObject, TProperty>> expression) {
    var member = expression.Body as MemberExpression;
    if(member != null) {
        return member.Member;
    }
    throw new ArgumentException("Member does not exist.");
}
Run Code Online (Sandbox Code Playgroud)

这么叫...

myDropDownList.populate(states,
    school => school.stateCode,
    school => school.stateName);
Run Code Online (Sandbox Code Playgroud)