[英]How to create properties with “delegated” accessors?
I'm new to c# and have been puzzling over this for a couple of days.我是 c# 的新手,几天来一直对此感到困惑。 Basically I want to create a type of property with getter and setter logic delegated to a base type to which this parameter belongs.
基本上,我想创建一种属性类型,将 getter 和 setter 逻辑委托给该参数所属的基本类型。
This is just one application: a property whose value is set by, say, the registry or some config file.这只是一个应用程序:一个属性,其值由注册表或某个配置文件设置。
Any suggestions?有什么建议么? I've thought about using
DefaultPropertyAttribute
, but I can't quite see how not to write all the logic necessary with each accessor.我考虑过使用
DefaultPropertyAttribute
,但我不太明白如何不为每个访问器编写所有必要的逻辑。
Looks like this is what I want: http://www.sharpcrafters.com/postsharp看起来这就是我想要的: http://www.sharpcrafters.com/postsharp
"Write less code" Yup. “少写代码”是的。 That's it alright.
没关系。
I'm not proud of it:我并不以此为荣:
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% untested. 100% 未经测试。
UPDATE Using a combination of the above, and @hunter's answer, you could do something like:更新结合使用上述内容和@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
}
With that, you can now do something like:有了它,您现在可以执行以下操作:
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; }
}
}
Using this stupid class:使用这个愚蠢的 class:
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; }
}
}
you can do something like this:你可以这样做:
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; }
}
}
Of course this won't handle every case but it might get you on the "right" track...当然,这不会处理所有情况,但它可能会让你走上“正确”的轨道......
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.