[英]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();
但是,现在是您重新设计例程的时候了:
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.