C# 有没有办法创建一个行为与dynamic或ExpandooObject相同的类?
我想创建一个具有固定属性的类,并能够将其扩展为动态或扩展对象可以。 e、 g: 用法:C# 有没有办法创建一个行为与dynamic或ExpandooObject相同的类?,c#,dynamic,expandoobject,C#,Dynamic,Expandoobject,我想创建一个具有固定属性的类,并能够将其扩展为动态或扩展对象可以。 e、 g: 用法: DynamicInstance myCustomObj = new DynamicInstance(); myCustomObj.FixedTestProperty = "FixedTestValue"; myCustomObj.DynamicCreatedTestProperty = "Custom dynamic property value"; 最后,如果我用json.net或其他东西序列化该类,输
DynamicInstance myCustomObj = new DynamicInstance();
myCustomObj.FixedTestProperty = "FixedTestValue";
myCustomObj.DynamicCreatedTestProperty = "Custom dynamic property value";
最后,如果我用json.net或其他东西序列化该类,输出如下内容:
{
FixedTestProperty: 'FixedTestValue',
DynamicCreatedTestProperty: 'Custom dynamic property value'
}
您需要继承
DynamicObject
并重写TryGetMember
和TrySetMember
方法。下面是一个类,它有一个名为one
的属性。但是,您可以动态添加更多内容
public class ExpandOrNot : DynamicObject
{
public string One { get; set; }
// The inner dictionary.
Dictionary<string, object> dictionary
= new Dictionary<string, object>();
// This property returns the number of elements
// in the inner dictionary.
public int Count
{
get
{
return dictionary.Count;
}
}
// If you try to get a value of a property
// not defined in the class, this method is called.
public override bool TryGetMember(
GetMemberBinder binder, out object result)
{
// Converting the property name to lowercase
// so that property names become case-insensitive.
string name = binder.Name.ToLower();
// If the property name is found in a dictionary,
// set the result parameter to the property value and return true.
// Otherwise, return false.
return dictionary.TryGetValue(name, out result);
}
// If you try to set a value of a property that is
// not defined in the class, this method is called.
public override bool TrySetMember(
SetMemberBinder binder, object value)
{
// Converting the property name to lowercase
// so that property names become case-insensitive.
dictionary[binder.Name.ToLower()] = value;
// You can always add a value to a dictionary,
// so this method always returns true.
return true;
}
}
更多信息
这可以在DynamicObject上使用TrySetMember
下面的示例演示了如何操作:那么,您尝试了什么?从
DynamicObject
继承确实是一种方法。您可以使用库。有关更多信息,请参见此内容。@s.m.是的,我想是的,但在这个实现中,我缺少固定属性的intellisense。也许有办法避免这种情况。因为如果我没有这个属性的intellisense,我认为没有理由创建我自己的对象,而不是创建一个动态的foo=new ExpandoObject()。@Saravana谢谢,我看到了,但是在博客上发布了。我会看看这个回购协议。哦,好吧,我明白了,但是当我键入exp时,无法在IntelliSense上获得固定属性。如果引用类型为动态
,那么不,您将无法获得任何IntelliSense。但是如果你投到ExpandoOrNot
,你将获得该组织成员的智能。这是真的!谢谢还有一件事。你知道为什么JObject.FromObject(exp)返回一个空的JObject吗?
public class ExpandOrNot : DynamicObject
{
public string One { get; set; }
// The inner dictionary.
Dictionary<string, object> dictionary
= new Dictionary<string, object>();
// This property returns the number of elements
// in the inner dictionary.
public int Count
{
get
{
return dictionary.Count;
}
}
// If you try to get a value of a property
// not defined in the class, this method is called.
public override bool TryGetMember(
GetMemberBinder binder, out object result)
{
// Converting the property name to lowercase
// so that property names become case-insensitive.
string name = binder.Name.ToLower();
// If the property name is found in a dictionary,
// set the result parameter to the property value and return true.
// Otherwise, return false.
return dictionary.TryGetValue(name, out result);
}
// If you try to set a value of a property that is
// not defined in the class, this method is called.
public override bool TrySetMember(
SetMemberBinder binder, object value)
{
// Converting the property name to lowercase
// so that property names become case-insensitive.
dictionary[binder.Name.ToLower()] = value;
// You can always add a value to a dictionary,
// so this method always returns true.
return true;
}
}
dynamic exp = new ExpandOrNot { One = "1" };
exp.Two = "2";