如何在C#中通过反射迭代时跳过一些类字段?

时间:2015-10-09 15:09:53

标签: c# .net asp.net-mvc model-view-controller reflection

我有与ASP.NET MVC视图紧密绑定的类。 对于他们的字段/属性(列),我必须使用Guid.NewGuid()生成一个唯一的名称。这样,每次打开视图时,对于与该类中特定字段/列相关联的每个控件都会有新的唯一名称。

但是,我想在生成唯一名称时跳过一些属性。因为,这些属性是隐藏的输入或占位符用于其他特定目的。什么可能是好方法?我应该为此应用自定义属性吗?在迭代字段期间,我只是跳过这些字段。

例如,班级是“

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; }
}

我怎样才能做到这一点?

3 个答案:

答案 0 :(得分:4)

以下是如何使用它的完整示例:

[AttributeUsage(AttributeTargets.Property, Inherited = true, AllowMultiple = false)]
public class NotRequiredForUniqueNameAttribute : Attribute { }

NotRequiredForUniqueNameAttribute适用于您不想使用的属性,因此您的班级将成为:

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;
    }
}

答案 1 :(得分:2)

这样做的一种可能方法是定义自定义属性,如果已分配属性,则忽略该属性。

public sealed class SkipPropertyAttribute: Attribute
{  
}

在你的班上:

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方法查明属性是否已定义。

答案 2 :(得分:0)

对于后人来说,这是没有旗帜的脏版本。

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;
        }
    }
}