C#接受字符串参数的函数:如何重构使用强类型的东西?

时间:2010-10-28 01:22:40

标签: c# automapper

我有这个C#代码可以正常运行,它可以抓取任意两个字段并将它们放入下拉列表的列表中:

var myDDL = GetDDLValues<Product>( myContact, "contactid", "companyname");

我希望将两个字符串参数放在除字符串之外的其他内容中。这样做真的很不错:

GetDDLValues<Product>( myContact, p => p.contactid, p => p.companyname)

这是它调用的代码(sweko反映谢谢!):

private object GetProperty(object obj, string propertyName)
{
    PropertyInfo pi = obj.GetType().GetProperty(propertyName);
    object value = pi.GetValue(obj, null);
    return value;
}

public  IList<DDLValues> GetDDLValues<T>(IList<T> objectListToMap, 
                         string textProperty, string valueProperty)
{   
    if( objectListToMap != null && objectListToMap.Count > 0)
    {
        Mapper.CreateMap< T, DDLValues>()
              .ForMember( dest => dest.text, 
                           opt => opt.MapFrom(src => textProperty))
              .ForMember( dest => dest.value, 
                           opt => opt.MapFrom(src => valueProperty));
        return Mapper.Map<IList<T>, IList<DDLValues>>(objectListToMap);
    }
    else
    {
        return null;
    }
}

3 个答案:

答案 0 :(得分:2)

从字符串构建动态查询:

public class Product 
{ 
    public long ID { get; set; } 
    public string Name { get; set; } 
    public DateTime Date { get; set; } 
} 


static void Main(string[] args) 
{ 
    List<Product> products = (from i in Enumerable.Range(1, 10) 
                          select new Product { ID = i, Name = "product " + i, Date = DateTime.Now.AddDays(-i) }).ToList();  //the test case 

    const string SortBy = "Date";  // to test you can change to "ID"/"Name" 

    Type sortType = typeof(Product).GetProperty(SortBy).PropertyType;     // DateTime 
    ParameterExpression sortParamExp = Expression.Parameter(typeof(Product), "p");    // {p} 
    Expression sortBodyExp = Expression.PropertyOrField(sortParamExp, SortBy);   // {p.DateTime} 
    LambdaExpression sortExp = Expression.Lambda(sortBodyExp, sortParamExp);   //   {p=>p.DateTime} 
    var OrderByMethod = typeof(Enumerable).GetMethods().Where(m => m.Name.Equals("OrderBy") && m.GetParameters().Count() == 2).FirstOrDefault().MakeGenericMethod(typeof(Product), sortType); 
    var result = OrderByMethod.Invoke(products, new object[] { products, sortExp.Compile() }); 
} 

答案 1 :(得分:1)

如果DDLValues有一个带有text和value属性的构造函数,那么它应该相对简单。

IList<DDLValues> GetDDLValues<T>( IList<T> source, Func<T,DDLValues> selector )
    where T : class
{
   return source.Select( selector )
                .ToList();
}

被称为

var ddlList = GetDDLValues( contacts, p => new DDLValues( c.Name, p.ContactID.ToString() ) );

这假设DDLValues有一个构造函数,如:

public DDLValues( string text, string value ) { ... }

如果您从源代码中提取数据库,那么在应用选择器之前,您可能还需要使用ToList()实现查询,以确保它不会尝试将选择器转换为SQL表达式。 / p>

答案 2 :(得分:1)

fvanfosson是对的,Select()是最简单的;如果你想使用AutoMapper,你需要这样的东西..

public  IList<DDLValues> GetDDLValues<T>(IList<T> objectListToMap, 
                         Func<T, string> textSelector, Func<T, string> valueSelector)
{   
    if( objectListToMap == null || objectListToMap.Count == 0)
        return null;

    Mapper.CreateMap< T, DDLValues>()
          .ForMember( dest => dest.text, 
                       opt => opt.MapFrom(textSelector))
          .ForMember( dest => dest.value, 
                       opt => opt.MapFrom(valueSelector));
    return Mapper.Map<IList<T>, IList<DDLValues>>(objectListToMap);
}