Roy*_*mir 9 .net c# dynamic-language-runtime dynamic .net-4.0
我试图在运行时添加功能,类似于:
static void Main()
{
dynamic d = new Duck();
d.Quack =(Action) (() => Console.WriteLine("1")); //decalre a new method on runtime ??
d.Quack();
}
public class Duck : System.Dynamic.DynamicObject
{
//...
}
Run Code Online (Sandbox Code Playgroud)
'UserQuery.Duck'不包含'Quack'的定义
不动态应该允许我这样做吗?
全新ExpandoObject是唯一的解决方案吗?
我有我的鸭类已.我该如何制作Expando? - 我可以像鸭子一样做鸭子吗?
gid*_*eon 15
您不能将任何类型(甚至函数)的属性添加到现有类型.
dynamic d = new Duck();
d.Quack = "Quack";//fails because there is no such property on duck
Run Code Online (Sandbox Code Playgroud)
您可以使用ExpandoObject:
dynamic d = new ExpandoObject();
d.Quack = (Action)(() => System.Console.WriteLine("1"));
d.Quack();
Run Code Online (Sandbox Code Playgroud)
不要与动态类型的作用混淆.
void speak(dynamic d)
{
d.Quack();//this is NOT checked at compile time
}
Run Code Online (Sandbox Code Playgroud)
现在我可以这样做了:speak(new Duck());并且speak(new Goose());,如果它们都有Duck并且Goose有方法Quack(),它将编译并运行,如果它们没有,它会引发异常.(你得到的那个)
在dynamic类型上调用方法/属性时,它仅在运行时解析该方法/属性,并且不进行编译器检查.
ExpandoObject允许您动态创建属性.
要回答关于注释的问题,我看到它的方式是,如果您需要自己的类,需要能够创建新属性,您可以从DynamicObject继承.像这样(改编自这个msdn页面):
class DynamicDuck : DynamicObject
{
Dictionary<string, object> dictionary
= new Dictionary<string, object>();
public int Count
{
get
{
return dictionary.Count;
}
}
public override bool TryGetMember(
GetMemberBinder binder, out object result)
{
string name = binder.Name.ToLower();
return dictionary.TryGetValue(name, out result);
}
public override bool TrySetMember(
SetMemberBinder binder, object value)
{
dictionary[binder.Name.ToLower()] = value;
return true;
}
}
Run Code Online (Sandbox Code Playgroud)
然后你可以这样做:
dynamic d = new DynamicDuck();
d.firstname = "Gideon";
d.Quack = (Action)(() => System.Console.WriteLine("Quack"));
Run Code Online (Sandbox Code Playgroud)