繁体   English   中英

获取具有类似名称的属性列表以循环c#

[英]Getting a Property list with similar name for looping c#

我有一堂课,有几个属性

public class Hotel
{
   public string ID {get; set;}
   public string Name {get; set;}
   public string Location {get; set;}
   public Image Image1 {get; set;}
   public Image Image2 {get; set;}
   public Image Image3 {get; set;}
   public Image Image4 {get; set;}
}

我想获取以属性名称“ Image”开头的所有属性的列表

public List<Image> GetImageList(Hotel hotel)
{
  List<Image> imageList = new List<Image>();
  foreach(var item in <ImageList>)
  {
    rest of the code .....
  }

  return imageList ;
}

从技术上讲,作为一种快速而肮脏的解决方案,您可以尝试反射

   using System.Reflection;

   ...

   // Properties; some conditions like property.CanRead && property.CanWrite 
   // can well appear redundant, but since the class is not yours,
   // better be a bit paranoic esp. having run into a bad design 
   var properties = hotel
     .GetType()
     .GetProperties(BindingFlags.Public | BindingFlags.Instance)
     .Where(property => property.CanRead && property.CanWrite) // Not necessary 
     .Where(property => property.Name.StartsWith("Image"))
     .Where(property => property.PropertyType == typeof(Image)); // Not necessary

   // Properties' values, i.e. images
   List<Image> list = properties
     .Select(property => property.GetValue(hotel) as Image)
     .Where(image => image != null) // if you want to filter out nulls
     .ToList(); 

但是,现在是您重新设计例程的时候了:

  1. 规范化数据库表(将图像推送到单独的表中)
  2. Image1..Image4 重新设计IList<Image>或类似的collection

首先,您可以使用Reflection获取所有PropertyInfos ,并在使用不同的Hotel实例调用GetImageList时重用它们:

private static List<PropertyInfo> hotelImages = GetHotelImageProperties();

private static List<PropertyInfo> GetHotelImageProperties()
{
    return typeof(Hotel)
        .GetProperties(BindingFlags.Instance | BindingFlags.Public)
        .Where(x => x.PropertyType == typeof(Image))
        .Where(x => x.CanRead)
        .Where(x => x.Name.StartsWith("Image"))
        .ToList();
}

然后,每次调用GetImageList ,只需获取属性的值即可:

public static List<Image> GetImageList(Hotel hotel)
{
    return hotelImages
        .Select(x => x.GetValue(hotel))
        .Cast<Image>()
        .ToList();
}

随着中说,它注意到反映很慢 ,当不真正需要的应该是可以避免的,还不止这些,性质很可能在编译时已知或可以表示为一些很重要IEnumerable<Image> ,以便更好的设计(更加灵活,快速且类型安全)。

如果它是从数据库或其他方案生成的,则应考虑将其表示或将其生成为某种集合类型。

以这种方式获取属性需要反思,因为反思对性能并没有太大的帮助。 我为您提供了更好的解决方案:

public class Hotel
{
    public string ID {get; set;}
    public string Name {get; set;}
    public string Location {get; set;}
    public List<Image> Images {get; set;}
}

这样您就可以使用:

Hotel hotel = new Hotel();
// Set properties
List<Image> imagesFromHotel = hotel.Images;

这样难道不是很容易吗? 您还可以轻松添加更多图像。 您无需为更多图像添加更多属性。

您可以使用反射在Hotel属性中循环,并从Image类型中获取值:

public List<Image> GetImageList(Hotel hotel)
    {
        List<Image> imageList = new List<Image>();
        var type = hotel.GetType();
        var propertyInfos = type.GetProperties();
        foreach (var item in propertyInfos)
        {
            if (item.Name.StartsWith("Image") && item.PropertyType==typeof(Image))
            {
                imageList.Add((Image)item.GetValue(hotel));
            }
        }

        return imageList;
    }

这会给你的枚举序列Image返回的Image与以“图像”开头的名称每个公共属性:

var images =
    from   property in hotel.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance)
    where  property.Name.StartsWith("Image") && property.PropertyType == typeof(Image)
    select (Image) property.GetValue(hotel);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM