实现通用设置类的最佳方法-反映了“获取/设置属性"? [英] Best way to implement generic setting class - Get/Set Properties reflected?

查看:88
本文介绍了实现通用设置类的最佳方法-反映了“获取/设置属性"?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我不知道如何制作通用设置类,希望您能为我提供帮助.
首先,我想要一个设置文件解决方案.为此,我创建了一个Singleton,如下所示:

I don't know how I can make a generic settings class and hope that you can help me.
First of all I want a single settings file solution. For this I have created a Singleton like this:

public sealed class Settings
{
  private static readonly Lazy<Settings> _instance = new Lazy<Settings>(() => new Settings());
  private Dictionary<string, object> m_lProperties = new Dictionary<string, object>();

  public void Load(string fileName)
  {
    throw new NotImplementedException();  
  }

  public void Save(string fileName)
  {
    throw new NotImplementedException();
  }

  public void Update()
  {
    throw new NotImplementedException();
  }

  /// <summary>
  /// Gets the propery.
  /// </summary>
  /// <param name="propertyName">Name of the property.</param>
  /// <returns></returns>
  public string GetPropery(string propertyName)
  {
    return m_lProperties[propertyName].ToString() ?? String.Empty;
  }

  /// <summary>
  /// Gets the propery.
  /// </summary>
  /// <param name="propertyName">Name of the property.</param>
  /// <param name="defaultValue">The default value.</param>
  /// <returns></returns>
  public string GetPropery(string propertyName, string defaultValue)
  {
    if (m_lProperties.ContainsKey(propertyName))
    {
      return m_lProperties[propertyName].ToString();
    }
    else
    {
      SetProperty(propertyName, defaultValue);
      return defaultValue;
    }
  }

  /// <summary>
  /// Sets the property.
  /// </summary>
  /// <param name="propertyName">Name of the property.</param>
  /// <param name="value">The value.</param>
  public void SetProperty(string propertyName, string value)
  {
    if (m_lProperties.ContainsKey(propertyName))
      m_lProperties[propertyName] = value;
    else
      m_lProperties.Add(propertyName, value);
  }
}

但是我认为更好的方法是将属性放在类中,并且可以通过反射来获取属性.
-您能帮我实现这样的事情吗?
-是否可以为属性赋予"encrypted = true"之类的属性? -将设置保存/加载到xml文件中的最佳方法是什么?

But I think the better way is that the properties are in the classes and I can get the properties through reflection.
- Can you help me to implement something like this?
- Is it possible to give properties attributes like "encrypted = true"? - Whats the best way to save / load the settings in a xml file?

已更新
这是一个如何使用实际设置的示例:

Updated
Here is a example how to use the settings actual:

class Test()
{
  private string applicationPath;
  private string configurationPath;
  private string configurationFile;

  public Test()
  {
    applicationPath = Settings.Instance.GetPropery("ApplicationPath", AppDomain.CurrentDomain.BaseDirectory);
    configurationPath = Settings.Instance.GetPropery("ConfigurationPath", "configurations");  
    configurationFile = Settings.Instance.GetPropery("ConfigurationFile", "application.xml");  
    // ... Load file with all settings from all classes
  } 

推荐答案

这与我自己的代码相关.

This here is a rather relevant bit from my own code.

public class MyObject
{
    public string StringProperty {get; set;}

    public int IntProperty {get; set;}

    public object this[string PropertyName]
        {
            get
            {
                return GetType().GetProperty(PropertyName).GetGetMethod().Invoke(this, null);
            }
            set
            {
                GetType().GetProperty(PropertyName).GetSetMethod().Invoke(this, new object[] {value});
            }
        }
}

这是允许的吗?

MyObject X = new MyObject();
//Set
X["StringProperty"] = "The Answer Is: ";
X["IntProperty"] = 42;
//Get - Please note that object is the return type, so casting is required
int thingy1 = Convert.ToInt32(X["IntProperty"]);
string thingy2 = X["StringProperty"].ToString();

已更新:更多说明 这种工作方式是反射地访问 properties ,属性与字段的不同之处在于它们使用getter和setter,而不是直接声明和访问.您可以使用相同的方法来获取字段,或者获取字段,如果为空,则检查GetProperty的返回值,而不是简单地假设它起作用.而且,正如另一条评论中指出的那样,如果您使用不存在的属性按原样调用它,则该方法将中断,因为它缺少任何形式的错误捕获.我以最简单的形式而不是最可靠的形式显示了代码.

Updated: More Explanation The way this works is to reflectively access properties, properties are different from fields in that they use getters and setters, as opposed to being directly declared and accessed. You can use this same method to get fields, or to also get fields, if you null check the return from GetProperty instead of simply assuming it works. Also, as was pointed out in another comment, this will break if you call it as is with a property that doesn't exist, because it lacks any form of error catching. I showed the code in its simplest possible form, not its most robust form.

至于属性属性....该索引器需要在您要与其一起使用的类(或父类,我将其放在BaseObject上)中创建,因此可以在内部在其上实现属性给定属性,然后在访问属性时应用开关或对照属性进行检查.也许使所有属性成为实现Object Value; Bool Encrypted;的其他自定义类,然后从那里开始对其进行处理,这实际上仅取决于您要获得的幻想程度和要编写的代码量.

As far as property attributes....that indexer needs to be created inside the class you want to use it with (or a parent class, I have it on my BaseObject), so internally you can implement attributes on given properties and then apply switches or checks against the properties when they are accessed. Maybe make all the properties some other custom class where you implement Object Value; Bool Encrypted; then work on it as needed from there, it really just depends on how fancy you want to get and how much code you want to write.

这篇关于实现通用设置类的最佳方法-反映了“获取/设置属性"?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆