65.9K
CodeProject 正在变化。 阅读更多。
Home

使用 Dynamic 关键字进行鸭子类型

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.72/5 (35投票s)

2013 年 5 月 24 日

CPOL

1分钟阅读

viewsIcon

47387

请勿在家尝试。

引言

免责声明

孩子们,不要在家尝试。是的,我们正在使用您可以在 .NET 语言的橱柜中轻松找到的关键字和类,但请不要像这里描述的那样混合这些关键字。否则可能会造成致命后果(对您的工作和别人的理智而言)。您即将见证的编程是由一位专业的、发育不良的开发者完成的。

现在,让我们炸毁一些你乏味乏味的编程观念吧!

Ruby 等语言中一个有趣的地方是鸭子类型,即“如果它走起来像鸭子,如果它叫起来像鸭子,如果你的院子里到处都是鸭屎,那么,它一定是鸭子!” 当然,对于像 C# 这样强类型语言,我们无法做到一些令人震惊的在弱类型语言中可以看到的惊人事情。相反,我们不得不依赖面向对象的概念,如继承、多态和接口,以实现某种程度的酷炫效果。

但是不再了!随着“dynamic”关键字的出现,世界已经成为所有嘎嘎叫的东西的游乐场!

强类型化的枷锁…

哦,为了强类型化,我们不得不做多么无聊的事情

public interface IQuack
{
  void Talk();
}

public class Duck : IQuack
{
  public void Talk() {Console.WriteLine("Quack");}
}

public class Goose : IQuack
{
  public void Talk() { Console.WriteLine("Honk"); }
}

它们束缚我们,限制我们…

static void Speak(IQuack bird)
{
  bird.Talk();
}

IQuack bird1 = new Duck();
IQuack bird2 = new Goose();
Speak(bird1);
Speak(bird2);

嘎嘎
喔喔

但摆脱接口的枷锁,让我们自由!

public class DynoDuck
{
  public void Talk() { Console.WriteLine("Dyno-Quack!"); }
}

public class DynoGoose
{
  public void Talk() { Console.WriteLine("Dyno-Honk!"); }
}

我们成为自由人(男性、女性和鸟类)!

static void Speak(dynamic d)
{
  d.Talk();
}

dynamic dynoBird1 = new DynoDuck();
dynamic dynoBird2 = new DynoGoose();
Speak(dynoBird1);
Speak(dynoBird2);

动态嘎嘎!
动态喔喔!

摆脱种族、信仰或……类的所有限制!

static void Speak(dynamic d, string outWithIt)
{
  d.Talk(outWithIt);
}

static dynamic InMyImage(string method, Action<string> action)
{
  dynamic dyn = new ExpandoObject();
  ((IDictionary<String, Object>)dyn)[method] = action;
  return dyn;
} 

与神一起翱翔!

var actor = (Action<string>) ((mySpeech) => Console.WriteLine(mySpeech));

dynamic dyn1 = InMyImage("Talk", actor);
dynamic dyn2 = InMyImage("Talk", actor);

Speak(dyn1, "Rise, my fellow ducks!");
Speak(dyn2, "To Canada or bust!"); 

起来吧,我的鸭子同胞们!
前往加拿大,否则就完蛋!

就像伊卡洛斯一样,坠回地球

当我们意识到自由是有代价的:完全的编码混乱!

© . All rights reserved.