首页 > 解决方案 > 防止在 .NET 中设置属性

问题描述

我想在创建模型时实施一些访问限制。目前我的代码看起来更像这样。

public Model GetModel()
{
    Model model = new Model();
    if (isAllowedToSet(Field.A))
        model.FieldA = 1;
    if (isAllowedToSet(Field.B))
        model.FieldB = 2;
    if (isAllowedToSet(Field.C))
        model.FieldC = 3;
    return model;
}
private bool isAllowedToSet(Field field)
{
    return (field == Field.A); //Here comes some real logic
}
class Model
{
    public int FieldA { get; set; }
    public int FieldB { get; set; }
    public int FieldC { get; set; }
}

如何更聪明地做到这一点?我正在考虑使用 FieldAttribute,但我还没有找到解决方案。还是有其他方法?

标签: c#.netcustom-attributes

解决方案


嗯,是的,你可以用反射和属性来做到这一点

public class Model
{
    [ReadOnly(true)]
    public int FieldA { get; set; }
    public int FieldB { get; set; }
    public int FieldC { get; set; }
}

public Model GetModel()
{
    Model model = new Model();

    if (isAllowedToSet(() => model.FieldA))
        model.FieldA = 1;

    if (isAllowedToSet(() => model.FieldB))
        model.FieldB = 2;

    if (isAllowedToSet(() => model.FieldC))
        model.FieldC = 3;

    return model;
}

private bool isAllowedToSet<T>(Expression<Func<T>> propertyExpression)
{
    var propertyName = ((MemberExpression)propertyExpression.Body).Member.Name;            
    Attribute readonlyAtt = TypeDescriptor.GetProperties(this)[propertyName].Attributes[typeof(ReadOnlyAttribute)];

    return readonlyAtt == null || readonlyAtt.Equals(ReadOnlyAttribute.No);
}

你是否应该完全是另一回事,因为这似乎是一个解决问题的方法,它可能有一个更优雅的解决方案,不涉及反射(除了其他任何东西之外,它都很慢)。

如果您可以详细说明您尝试这样做的原因,您可能会得到更好的回应。


推荐阅读