具有用户可配置属性“可见性”的对象

本文关键字:可见性 对象 属性 用户 配置 | 更新日期: 2023-09-27 18:35:59

我有一个带有一堆属性的 User 对象。我有一个要求,即当用户设置其信息时,他们需要能够声明其配置文件的哪些属性对其他人可见。

我设想的方式是添加一个额外的属性 - 一个字符串列表,其中包含公开可见的属性名称。然后,我可以实现一个名为 ToPublicView() 或类似方法的方法,该方法将使用反射将非公共属性设置为 null 或默认值。

这是一种合理的方法,还是有更好的方法?

具有用户可配置属性“可见性”的对象

我认为这是最简单的选择。如果反射开始影响您的性能,您可能需要一个属性委托字典来访问值。

由于要求不是具有动态属性,而只是标记现有属性,因此以动态方式(如属性对象列表)拥有所有属性是没有意义的。此外,将它们作为实际属性将使代码在必须将其用于应用程序的其余部分时更具可读性。

在这种情况下,如果可能的话,我建议简单地列出您的属性,例如:

public Class Property<T>
{
    public Property(string name, bool visible, T value)
    {
        Name = name;
        Visible = visible;
        Value = value;
    }
    string Name { get; set; }
    bool Visible { get; set; }
    T Value { get; set; }
}

然后,您可以像这样创建一个属性列表:

List<Property> properties = new List<Property>();
properties.Add(new Property<string>("FirstName", true, "Steve"));

如果你今天需要能够设置可见性,你可能还需要在明天设置其他元属性。 颜色? 必需/可选? 大小? 等。 拥有自己的属性类型可以让您将来轻松扩展它。

什么?不。如果这是需求,那么用户属性不应该用实际属性来实现,而是使用某种 IEnumerable 和属性对象,其中每个属性都有其可见性等。

可以使用,可能是自定义动态对象实现的某种组合

编辑

  //custom property class
  public class MyProperty
  {
      public bool IsVisible { get; set; }
      public string PropertyName { get; set; }
  }
  public class Dymo: DynamicObject
  {
      Dictionary<MyProperty, object> dictionary
          = new Dictionary<MyProperty, object>();
      public override bool TryGetMember(
          GetMemberBinder binder, out object result)
      {
          result = false;
          var prop = PropertyFromName(binder.Name);
          if (prop != null && prop.IsVisible)
              return dictionary.TryGetValue(prop, out result);
          return false;
      }
      public override bool TrySetMember(
          SetMemberBinder binder, object value)
      {
          var prop = PropertyFromName(binder.Name);
          if (prop != null && prop.IsVisible)
              dictionary[prop] = value;
          else
              dictionary[new MyProperty { IsVisible = true, PropertyName = binder.Name}] = value;
          return true;
      }
      private MyProperty PropertyFromName(string name)
      {
          return (from key in dictionary.Keys where key.PropertyName.Equals(name) select key).SingleOrDefault<MyProperty>();
      }

      public void SetPropertyVisibility(string propertyName, bool visibility)
      {
          var prop = PropertyFromName(propertyName);
          if (prop != null)
              prop.IsVisible = visibility;         
      }
  }

并像这样之后使用它。

dynamic dynObj = new Dymo();
dynObj.Cartoon= "Mickey" ;
dynObj.SetPropertyVisibility("Mickey", false); //MAKE A PROPERTY "INVISIBLE"