我有一个带有一堆属性的User对象。我要求说明当用户设置他们的信息时,他们需要能够说明他们的个人资料的哪些属性对其他人可见。
我设想的方式是添加一个额外的属性 - 一个字符串列表,其中包含公开可见的属性名称。然后,我可以实现一个名为ToPublicView()的方法或类似的方法,使用反射将非公共属性设置为null或default。
这是一种合理的方法,还是有更好的方法?
答案 0 :(得分:1)
在这种情况下,如果可能的话,我建议您只提供一个属性列表,例如:
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"));
如果您今天需要设置可见性,则可能需要明天设置其他元属性。颜色?必需/可选?尺寸?等等。拥有自己的Property属性允许您以后轻松扩展它。
答案 1 :(得分:1)
我认为这是最简单的选择。如果反射开始破坏你的表现,你可能想要一个property-delegate字典来访问这些值。
由于要求不是拥有动态属性而只是标记现有属性,因此以动态方式拥有所有属性(如属性对象列表)是没有意义的。此外,将它们作为实际属性将使代码在您必须将其用于应用程序的其余部分时更具可读性。
答案 2 :(得分:0)
什么?不。如果这是需求,那么用户属性应不用实际属性来实现,而是使用某种IEnumerable和Property对象,其中每个Property都有其可见性等。
答案 3 :(得分:0)
可以使用,也可以是自定义DynamicObject实现的某种组合
修改强>
//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"