C# 使用动态添加方法?

C# 使用动态添加方法?,c#,.net,dynamic,.net-4.0,dynamic-language-runtime,C#,.net,Dynamic,.net 4.0,Dynamic Language Runtime,我试图在运行时添加函数,类似于: 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 { //... } “UserQuery.Duck”

我试图在运行时添加函数,类似于:

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
{
   //...
}
“UserQuery.Duck”不包含“Quack”的定义

难道动态不应该允许我这样做吗

全新的
ExpandoObject
是唯一的解决方案吗


我已经有鸭子课了。我怎样才能让它膨胀我可以让duck像expando一样工作吗?

您不能将任何类型的属性(甚至函数)添加到现有类型。

dynamic d = new Duck();
d.Quack = "Quack";//fails because there is no such property on duck
不过,您可以使用:


不要混淆动态类型的作用

void speak(dynamic d)
{
 d.Quack();//this is NOT checked at compile time
}
现在我可以做:
speak(newduck())
说话(新鹅())Duck
Goose
都有方法
Quack()
,它将编译并运行,如果没有,它将引发异常。(和你得到的一样)

当您对
动态
类型调用方法/属性时,它只在运行时解析该方法/属性,而不执行编译器检查

ExpandoObject允许您动态创建属性


在我看来,如果您需要自己的类,而该类需要创建可以从中继承的新属性,那么就可以回答您关于注释的问题。像这样(改编自):


由于一些完全不清楚的原因,我的帖子被删除了。顺便说一句,您不能从ExpandooObject派生,如果您想让您的对象表现为那样,您有两种解决方案,imo:1。创建Expando并最初添加Duck中的所有属性和方法,不要使用Duck。2.生成您自己的ExpandoObject。请看这里:获取更详细的示例并从中派生Duck.thnaks,但我为什么要从System.Dynamic.DynamicObject继承呢?我看到的唯一场景是覆盖tryGetXXX等。。方法…如果您不想将类用作“字典”,例如,如果它表示可以动态访问列和元素的xml或csv文件,如
file.nameOfSecondColumn[row]
void speak(dynamic d)
{
 d.Quack();//this is NOT checked at compile time
}
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;
    }
 }
dynamic d = new DynamicDuck();
d.firstname = "Gideon";
d.Quack = (Action)(() => System.Console.WriteLine("Quack"));