此刻,我正在研究功能,涉及将数据导出和导入Xlsx文件。我想做的是:我想要一个可以放在这样的属性上方的属性。
public class MyClass
{
[XlsxColumn("Column 1")]
public string myProperty1 { get; set; }
public int myProperty2 { get; set; }
}
到目前为止,我还没有遇到任何问题,但是我想“存储对使用XlsxColumn属性标记的属性的引用”。我正在使用反射 在列表中存储属性数据
var propsList = MyClass.GetProperties().Where(
prop => Attribute.IsDefined(prop, typeof(XlsxColumn)));
我有一个列表,其中所有属性都标记有XlsxColumn(在此示例中仅是myProperty1)。
编辑:问题是我不知道如何遍历MyClass中的属性,而仅遍历具有XlsxColumn属性的属性(因此所有的PropertyInfo对象都存储在propsList变量中),而无需借助将每个对象保存到Xlsx文件的反射。
我仅限于.NET 4.0。
感谢您的时间。
答案 0 :(得分:0)
我必须说,我不确定这是否是您要寻找的解决方案。因为我不太清楚你的问题是什么。好吧,我已经尽力提供了答案。
我去了CachingPropetyProvider
的静态类,但是您可以去实例类,并使用依赖项注入库并将其也用作Singleton
。而且,我写了广泛的评论,所以它尽可能自我解释。
让我们定义MyClass。我还特意做了一点改动。
public class MyClass
{
[XlsxColumn("Column 1")]
public string MyProperty1 { get; set; }
[XlsxColumn("Column 2")]
public int MyProperty2 { get; set; }
}
我还定义了一个MetaInfo
类来保存缓存的信息。
public class MetaInfo {
/// <summary>
/// Immutable class for holding PropertyInfo and XlsxColumn info.
/// </summary>
/// <param name="info">PropertyInfo</param>
/// <param name="attr">XlsxColumn</param>
public MetaInfo(PropertyInfo info, XlsxColumn attr) {
PropertyInfo = info;
Attribute = attr;
}
/// <summary>
/// PropertyInfo. You may want to access the value inside the property.
/// </summary>
public PropertyInfo PropertyInfo { get; }
/// <summary>
/// Attribute. You may want to access information hold inside the attribute.
/// </summary>
public XlsxColumn Attribute { get; }
}
最后是主要人物。这个人负责提供有关类的所有数据
public class CachingPropProvider {
/// <summary>
/// Holds the meta information for each type.
/// </summary>
private static readonly ConcurrentDictionary<Type, List<MetaInfo>> TypeCache;
/// <summary>
/// Static constructor is guaranteed to run only once.
/// </summary>
static CachingPropProvider() {
//Initialize the cache.
TypeCache = new ConcurrentDictionary<Type, List<MetaInfo>>();
}
/// <summary>
/// Gets the MetaInfo for the given type. Since We use ConcurrentDictionary it is thread safe.
/// </summary>
/// <typeparam name="T">Type parameter</typeparam>
public static IEnumerable<MetaInfo> GetCachedStuff<T>() {
//If Type exists in the TypeCache, return the cached value
return TypeCache.GetOrAdd(typeof(T),Factory);
}
/// <summary>
/// Factory method to use to extract MetaInfo when Cache is not hit.
/// </summary>
/// <param name="type">Type to extract info from</param>
/// <returns>A list of MetaInfo. An empty List, if no property has XlsxColumn attrbiute</returns>
private static List<MetaInfo> Factory(Type @type) {
//If Type does not exist in the TypeCahce runs Extractor
//Method to extract metainfo for the given type
return @type.GetProperties().Aggregate(new List<MetaInfo>(), Extractor);
}
/// <summary>
/// Extracts MetaInfo from the given property info then saves it into the list.
/// </summary>
/// <param name="seedList">List to save metainfo into</param>
/// <param name="propertyInfo">PropertyInfo to try to extract info from</param>
/// <returns>List of MetaInfo</returns>
private static List<MetaInfo> Extractor(List<MetaInfo> seedList,PropertyInfo propertyInfo) {
//Gets Attribute
var customattribute = propertyInfo.GetCustomAttribute<XlsxColumn>();
//If custom attribute is not null, it means it is defined
if (customattribute != null)
{
//Extract then add it into seed list
seedList.Add(new MetaInfo(propertyInfo, customattribute));
}
//Return :)
return seedList;
}
}
最后,让我们看看如何使用该解决方案。实际上,这非常简单。
//Has 2 values inside
var info = CachingPropProvider.GetCachedStuff<MyClass>();
答案 1 :(得分:0)
MyClass.GetProperties()
不起作用,因为您必须获取类的类型才能调用GetProperties method。否则,您将调用MyClass类中定义的静态方法GetProperties。
var propsList = typeof(MyClass).GetProperties().Where(
prop => prop.IsDefined(typeof(XlsxColumnAttribute), false)).ToList();
如果您只想使用名称(IList<string>
):
var propsList = typeof(Excel).GetProperties().Where(
prop => prop.IsDefined(typeof(XlsxColumnAttribute), false))
.Select(prop=> prop.Name)
.ToList();
要使用.Where
,您必须包括System.Linq