如何在 C# 中通过反射迭代时跳过某些 class 字段?
How to skip some of the class fields while iterating by reflection in C#?
我有 classes 那些与 ASP.NET MVC 视图紧密绑定的。
针对他们的 fields/properties(列),我必须使用 Guid.NewGuid() 生成一个唯一的名称。这样,每次打开视图时,每个与 class.
内的特定 field/column 关联的控件都会有新的唯一名称
但是,我想在生成唯一名称时跳过一些属性。因为,这些属性要么是隐藏的输入,要么是用于其他特定目的的占位符。什么是好的方法?我应该为此应用自定义属性吗?在字段迭代期间,我会简单地跳过这些字段。
例如 class 是“
public abstract class DashboardModuleCommonSettings
{
public int ForwarderId { get; set; }
public int ClientSubsidiaryId { get; set; }
public bool IsContentUpdateable { get; set; }
public int? AfterTime { get; set; }
public string Title { get; set; }
[Not Required to be iterated for generating unique name]
public string ModuleSettingsPopupName { get; set; }
[Not Required to be iterated for generating unique name]
public int ClientId { get; set; }
[Not Required to be iterated for generating unique name]
[HiddenInput(DisplayValue = false)]
public string CurrentLayout { get; set; }
}
我怎样才能做到这一点?
一种可能的方法是定义您的自定义属性并忽略 属性(如果已分配)。
public sealed class SkipPropertyAttribute: Attribute
{
}
在你的 class 上:
public abstract class DashboardModuleCommonSettings
{
public int ForwarderId { get; set; }
public int ClientSubsidiaryId { get; set; }
public bool IsContentUpdateable { get; set; }
public int? AfterTime { get; set; }
public string Title { get; set; }
[SkipProperty]
public string ModuleSettingsPopupName { get; set; }
[SkipProperty]
public int ClientId { get; set; }
[SkipProperty]
[HiddenInput(DisplayValue = false)]
public string CurrentLayout { get; set; }
}
您可以使用 Attribute.IsDefined
方法来查明属性是否已定义。
这是一个完整的使用示例:
[AttributeUsage(AttributeTargets.Property, Inherited = true, AllowMultiple = false)]
public class NotRequiredForUniqueNameAttribute : Attribute { }
NotRequiredForUniqueNameAttribute
应用于您不想使用的属性,因此您的 class 变为:
public abstract class DashboardModuleCommonSettings
{
public int ForwarderId { get; set; }
public int ClientSubsidiaryId { get; set; }
public bool IsContentUpdateable { get; set; }
public int? AfterTime { get; set; }
public string Title { get; set; }
[NotRequiredForUniqueName]
public string ModuleSettingsPopupName { get; set; }
[NotRequiredForUniqueName]
public int ClientId { get; set; }
[NotRequiredForUniqueName]
[HiddenInput(DisplayValue = false)]
public string CurrentLayout { get; set; }
}
然后当你想提取没有那个属性的属性时,你可以这样做:
public class TestClass
{
public static string GenerateUniqueName(DashboardModuleCommonSettings dmcs)
{
var propInfos = dmcs.GetType().GetProperties(
BindingFlags.Instance | BindingFlags.Public).Where(
p => p.GetCustomAttribute<NotRequiredForUniqueNameAttribute>() == null);
string uniqueName = "";
foreach (var propInfo in propInfos)
{
//Do something with the property info
}
return uniqueName;
}
}
为了后代,这里是没有标志的脏版本。
public abstract class DashboardModuleCommonSettings
{
public int ForwarderId { get; set; }
public int ClientSubsidiaryId { get; set; }
public bool IsContentUpdateable { get; set; }
public int? AfterTime { get; set; }
public string Title { get; set; }
public string __marker__ { get; }
public string ModuleSettingsPopupName { get; set; }
public int ClientId { get; set; }
public string CurrentLayout { get; set; }
}
public static class Extractor
{
public static IEnumerable<PropertyInfo> VisibleProperties<T>()
{
foreach (var p in typeof(T).GetProperties())
{
if ("__marker__".Equals(p.Name, StringComparison.InvariantCultureIgnoreCase)) yield break;
yield return p;
}
}
}
我有 classes 那些与 ASP.NET MVC 视图紧密绑定的。 针对他们的 fields/properties(列),我必须使用 Guid.NewGuid() 生成一个唯一的名称。这样,每次打开视图时,每个与 class.
内的特定 field/column 关联的控件都会有新的唯一名称但是,我想在生成唯一名称时跳过一些属性。因为,这些属性要么是隐藏的输入,要么是用于其他特定目的的占位符。什么是好的方法?我应该为此应用自定义属性吗?在字段迭代期间,我会简单地跳过这些字段。
例如 class 是“
public abstract class DashboardModuleCommonSettings
{
public int ForwarderId { get; set; }
public int ClientSubsidiaryId { get; set; }
public bool IsContentUpdateable { get; set; }
public int? AfterTime { get; set; }
public string Title { get; set; }
[Not Required to be iterated for generating unique name]
public string ModuleSettingsPopupName { get; set; }
[Not Required to be iterated for generating unique name]
public int ClientId { get; set; }
[Not Required to be iterated for generating unique name]
[HiddenInput(DisplayValue = false)]
public string CurrentLayout { get; set; }
}
我怎样才能做到这一点?
一种可能的方法是定义您的自定义属性并忽略 属性(如果已分配)。
public sealed class SkipPropertyAttribute: Attribute
{
}
在你的 class 上:
public abstract class DashboardModuleCommonSettings
{
public int ForwarderId { get; set; }
public int ClientSubsidiaryId { get; set; }
public bool IsContentUpdateable { get; set; }
public int? AfterTime { get; set; }
public string Title { get; set; }
[SkipProperty]
public string ModuleSettingsPopupName { get; set; }
[SkipProperty]
public int ClientId { get; set; }
[SkipProperty]
[HiddenInput(DisplayValue = false)]
public string CurrentLayout { get; set; }
}
您可以使用 Attribute.IsDefined
方法来查明属性是否已定义。
这是一个完整的使用示例:
[AttributeUsage(AttributeTargets.Property, Inherited = true, AllowMultiple = false)]
public class NotRequiredForUniqueNameAttribute : Attribute { }
NotRequiredForUniqueNameAttribute
应用于您不想使用的属性,因此您的 class 变为:
public abstract class DashboardModuleCommonSettings
{
public int ForwarderId { get; set; }
public int ClientSubsidiaryId { get; set; }
public bool IsContentUpdateable { get; set; }
public int? AfterTime { get; set; }
public string Title { get; set; }
[NotRequiredForUniqueName]
public string ModuleSettingsPopupName { get; set; }
[NotRequiredForUniqueName]
public int ClientId { get; set; }
[NotRequiredForUniqueName]
[HiddenInput(DisplayValue = false)]
public string CurrentLayout { get; set; }
}
然后当你想提取没有那个属性的属性时,你可以这样做:
public class TestClass
{
public static string GenerateUniqueName(DashboardModuleCommonSettings dmcs)
{
var propInfos = dmcs.GetType().GetProperties(
BindingFlags.Instance | BindingFlags.Public).Where(
p => p.GetCustomAttribute<NotRequiredForUniqueNameAttribute>() == null);
string uniqueName = "";
foreach (var propInfo in propInfos)
{
//Do something with the property info
}
return uniqueName;
}
}
为了后代,这里是没有标志的脏版本。
public abstract class DashboardModuleCommonSettings
{
public int ForwarderId { get; set; }
public int ClientSubsidiaryId { get; set; }
public bool IsContentUpdateable { get; set; }
public int? AfterTime { get; set; }
public string Title { get; set; }
public string __marker__ { get; }
public string ModuleSettingsPopupName { get; set; }
public int ClientId { get; set; }
public string CurrentLayout { get; set; }
}
public static class Extractor
{
public static IEnumerable<PropertyInfo> VisibleProperties<T>()
{
foreach (var p in typeof(T).GetProperties())
{
if ("__marker__".Equals(p.Name, StringComparison.InvariantCultureIgnoreCase)) yield break;
yield return p;
}
}
}