C#等价于Python属性自定义/Javascript对象文本
本文关键字:Javascript 对象 文本 自定义 等价于 Python 属性 | 更新日期: 2023-09-27 18:28:42
我喜欢Python的一点是可以自定义属性访问的方式:
class Foo(object):
def __getattr__(self, name):
if some_predicate(name):
# ...
else:
# Default behaviour
raise AttributeError
您可以使用Javascript的对象文字表示法更直接地执行类似的操作。
我的问题是:你怎么能在C#中实现类似的东西?正在重载"。"操作员是这样做的一种方式,但它不允许进入。
我脑海中的一个例子是这样定义一个类:
public class MyClass
{
public IDictionary Properties {get; private set;}
public MyClass(IDictionary properties)
{
this.Properties = properties;
}
// Overload the '.' operator - not allowed!
public static object operator .(MyClass inst, string name)
{
return inst.Properties[name];
}
}
使用这样的类:
class Program
{
static void Main(string[] args)
{
IDictionary properties = new Dictionary<string, string>() {
{ "prop1", "value1"}, { "prop2", "value2"} };
var my = new MyClass(properties);
System.Console.WriteLine(my.prop1); // Doesn't work!
}
}
(注意:我在这里问了一个关于C++的类似问题;最初是同一个问题,但为了更具体地针对每种语言进行了拆分。)
您有一个内置的对此的支持。您应该从DynamicObject派生类,并通过使用传递给构造函数的字典检查属性是否有效来覆盖它的TryGetMember/TrySetMember。
另一种选择是只使用ExpandoObject作为属性包。
然而,虽然您确实获得了动态语言所具有的一定程度的功能,但您却失去了C#的原生特性,如类型安全、编译时检查和IDE代码完成支持。
@galenus给出了我接受的答案,但为了记录在案,我想我应该为更新为使用DynamicObject的示例添加代码。
public class MyClass : DynamicObject
{
public IDictionary<string, object> Properties { get; private set; }
public MyClass(IDictionary<string, object> properties)
{
this.Properties = properties;
}
public override bool TryGetMember(GetMemberBinder binder, out object result)
{
return Properties.TryGetValue(binder.Name, out result);
}
}
class Program
{
static void Main(string[] args)
{
IDictionary<string, object> properties = new Dictionary<string, object>() {
{ "prop1", "value1"}, { "prop2", "value2"} };
dynamic my = new MyClass(properties);
System.Console.WriteLine(my.prop1);
}
}