如何使用“委派”创建属性访问器

本文关键字:属性 访问 创建 何使用 委派 | 更新日期: 2023-09-27 17:54:35

我是c#新手,这几天一直在为这个问题感到困惑。基本上,我想创建一个类型的属性,将getter和setter逻辑委托给该参数所属的基类型。

这只是一个应用程序:一个属性,它的值是由注册表或一些配置文件设置的。

  • get的属性处理程序会做一些事情,比如检查缓存值(或没有),如果没有缓存则检索值,缓存值(或没有)并返回它。
  • 设置器的行为将只允许属性处理程序设置值(如果可能的话)。

有什么建议吗?我考虑过使用DefaultPropertyAttribute,但我不太明白如何不为每个访问器编写所有必要的逻辑。


看起来这就是我想要的:http://www.sharpcrafters.com/postsharp

"少写代码"是的。没关系。

如何使用“委派”创建属性访问器

我并不为此感到骄傲:

public abstract class HorribleBaseType
{
  private Lazy<string> _connectionString;
  private Action<string> _connectionStringSetter;
  private Func<string> _connectionStringGetter;
  public HorribleBaseType(
    Func<string> connectionStringGetter, 
    Action<string> connectionStringSetter)
  {
    _connectionStringGetter = connectionStringGetter;
    _connectionStringSetter = connectionStringSetter;
    _connectionString = new Lazy<string>(connectionStringGetter);
  }
  public string ConnectionString
  {
    get { return _connectionString.Value; }
    set 
    { 
      _connectionStringSetter(value);
      _connectionString = new Lazy<string>(_connectionStringGetter);
    }
  }
}
public class HorribleType : HorribleBaseType
{
  public HorribleType()
    : base(() => MyConfiguration.ConnectionString,
           (v) => MyConfiguration.ConnectionString = v) { }
}

100%的未经测试。

UPDATE使用上面的组合,和@hunter的答案,你可以这样做:

public class DelegateProperty<T>
{
    #region Fields
    private readonly Func<T> _getter;
    private readonly Action<T> _setter;
    private Lazy<T> _lazy;
    #endregion
    #region Constructors
    public DelegateProperty(Func<T> getter, Action<T> setter)
    {
        _getter = getter;
        _setter = setter;
        _lazy = new Lazy<T>(getter);
    }
    #endregion
    #region Properties
    public T Value
    {
        get { return _lazy.Value; }
        set
        {
            _setter(value);
            _lazy = new Lazy<T>(_getter);
        }
    }
    #endregion
    #region Operators
    public static implicit operator T(DelegateProperty<T> prop)
    {
        return prop.Value; 
    }
    #endregion
}

现在,你可以这样做:

class Program
{
    static void Main(string[] args)
    {
        string name = "Matt";
        var prop = new DelegateProperty<string>(
            () => name,
            value => name = value);
        var test = new Test(prop);
        Console.WriteLine(test.Name);
        test.Name = "Ben";
        Console.WriteLine(name);
        Console.ReadKey();
    }
}
public class Test
{
    private readonly DelegateProperty<string> NameProperty;
    public Test(DelegateProperty<string> prop)
    {
        NameProperty = prop;   
    }
    public string Name
    {
        get { return NameProperty; }
        set { NameProperty.Value = value; }
    }
}

使用这个愚蠢的类:

public class Property<T>
{
    Func<T> _func;
    T _value;
    bool _fetched;
    public Property(Func<T> func)
    {
        _func = func;
    }
    public T Value
    {
        get 
        {
            if (!_fetched)
            {
                _value = _func();
                _fetched = true;
            }
            return _value;
        }
        set { _value = value; }
    }
}

你可以这样做:

public class TestClass
{
    Property<int> _propertyInt;
    public int MyInt
    {
        get { return _propertyInt.Value; }
        set { _propertyInt.Value = value; }
    }
    Property<string> _propertyString;
    public string MyString
    {
        get { return _propertyString.Value; }
        set { _propertyString.Value = value; }
    }
}
当然,这不会处理所有情况,但它可能会让你走上"正确"的轨道…