3

我有一个带有一些带有一些属性标记的道具的类。我想按特定顺序显示它们。到目前为止,我可以将它们按顺序排列,但不能按我想要的顺序排列。

这是带有属性的道具的简单示例

[IncludeInEditor]
[IsInPk]
ID
[IncludeInEditor(IsReadOnlyOnModify=true)]
Name
[IncludeInEditor]
Address
[IncludeInEditor]
DOB


The order that I want is:
  1st - Props with IsInPk attribute
  2nd - Props with IncludeInEditor(IsReadOnlyOnModify=true)
  3rd - Props with IncludeInEditor

到目前为止,我没有成功,也没有 100% 完成(仍然缺少 IsReadOnlyOnModify=true 部分)

var properties =
item.GetType().GetProperties()
.Where(p => p.GetCustomAttributes(true)
                            .OfType<IncludeInEditorAttribute>()
                            .Count() > 0)
                .Select (x => new 
                {
                    Property = x,
                    Attribute = (IsInPkAttribute)Attribute.GetCustomAttribute(x, typeof(IsInPkAttribute), true) 
                })
                .OrderBy(x => x.Attribute != null ? 1 : -1)
                .Select(x => x.Property)
                .ToArray();
4

2 回答 2

1

您可以创建自己的IComparer<T>实现来比较每个属性的属性:

public class AttributeComparer : IComparer<Attribute>
{
    public int Comparer(Attribute x, Attribute y)
    {
        if(x == null) return y == null ? 0 : -1;
        if(y == null) return 1;

        if(x is IsInPkAttribute) return (y is IsInPkAttribute) ? 0 : 1;
        else if(y is IsInPkAttribute) return -1;
        else
        {
            xa = (IncludeInEditorAttribute)x;
            ya = (IncludeInEditorAttribute)y;

            if(xa.IsReadOnlyOnModify == ya.IsReadOnlyOnModify) return 0;
            else return x.IsReadOnlyOnModify ? 1 : -1;
        }
    }
}

然后您的查询变为:

var properties = item.GetType().GetProperties()
    .Where(p => p.GetCustomAttributes(true)
                .OfType<IncludeInEditorAttribute>()
                .Any())
    .Select (x => new 
    {
        Property = x,
        Attribute = Attribute.GetCustomAttribute(x, typeof(IsInPkAttribute), true) ?? Attribute.GetCustomAttribute(x, typeof(IncludeInEditorAttribute, true))
    })
    .OrderBy(x => x.Attribute, new AttributeComparer())
    .Select(x => x.Property)
    .ToArray();
于 2012-09-19T21:46:02.920 回答
0

在李的帮助下,终于成功了。正确的代码是:

var properties =
                item.GetType().GetProperties()
                                .Where(p => p.GetCustomAttributes(true)
                                            .OfType<IncludeInEditorAttribute>()
                                            .Any())
                                .Select(x => new
                                {
                                    Property = x,
                                    Attribute = Attribute.GetCustomAttribute(x, typeof(IsInPkAttribute), true)
                                                    ?? Attribute.GetCustomAttribute(x, typeof(IncludeInEditorAttribute), true)
                                })
                                .OrderBy(x => x.Attribute, new IncludeInEditorAttributeComparer())
                                .Select(x => x.Property)
                                .ToArray();

Lee发送的这段代码,我做了一点改动。

public class IncludeInEditorAttributeComparer : IComparer<Attribute>
    {
        public int Compare(Attribute x, Attribute y)
        {
            //In this case we can assume that
            //won´t have null values

            if (x is IsInPkAttribute && !(y is IsInPkAttribute))
                return -1;
            else if (y is IsInPkAttribute && !(x is IsInPkAttribute))
                return 1;
            else 
            { 
                bool xa = (x is IncludeInEditorAttribute ? (x as IncludeInEditorAttribute).IsReadOnlyOnModify : false);
                bool ya = (y is IncludeInEditorAttribute ? (y as IncludeInEditorAttribute).IsReadOnlyOnModify: false);

                if (xa && !ya)
                    return -1;
                else if (ya && !xa)
                    return 1;
                else
                    return 0;
            }
        }
    }
于 2012-09-20T16:50:22.537 回答