我有一个包含多个属性的类
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 ;
}
答案 0 :(得分:2)
从技术上讲,作为快速而肮脏的解决方案,您可以尝试反射:
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>
或类似集合。 答案 1 :(得分:1)
首先,您可以使用PropertyInfos
获取所有Reflection
,并在使用不同GetImageList
个实例调用Hotel
时重复使用它们:
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>
以允许更好的设计(更灵活,更快速和类型安全)。
如果它是从数据库或其他方案生成的,您应该考虑将其表示或生成为某种集合类型。
答案 2 :(得分:0)
以这种方式获取属性需要反思,因为反射对于性能而言并不是很好。我为你找到了一个更好的解决方案:
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;
那不是更容易吗?您还可以更轻松地添加更多图像。您不需要为更多图像添加更多属性。
答案 3 :(得分:0)
您可以使用反射循环浏览酒店属性,并从图像类型中获取值:
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;
}
答案 4 :(得分:0)
这将为您提供一个可枚举的Image
序列,该序列为每个公共属性返回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);