# 多模式 .NET，第 8 部分：动态编程

### Ted Neward

``````class USD { }
class EUR { }
class Money<C> {
public float Quantity { get; set; }
public C Currency { get; set; }

public static Money<C> operator
+(Money<C> lhs, Money<C> rhs) {
return new Money<C>() {
Quantity = lhs.Quantity + rhs.Quantity,
Currency = lhs.Currency };
}

public Money<C2> Convert<C2>() where C2 : new() {
return new Money<C2>() { Quantity = this.Quantity,
Currency = new C2() };
}
}
``````

## 我的钱，您的钱，都是合法的真钱

``````interface ICurrency { }
class USD : ICurrency { }
class EUR : ICurrency { }
class Money<C> where C : ICurrency {
public float Quantity { get; set; }
public C Currency { get; set; }

public static Money<C> operator+(Money<C> lhs,
Money<C> rhs) {

return new Money<C>() {
Quantity = lhs.Quantity + rhs.Quantity,
Currency = lhs.Currency };
}

public Money<C2> Convert<C2>() where C2 : new() {
return new Money<C2>() { Quantity = this.Quantity,
Currency = new C2() };
}
}
``````

（当我们解决这个问题时，我们将添加构造函数以便于实例化 Money<>。）

``````interface ICurrency {
float Convert<C1, C2>(float from);
}
``````

``````class USD : ICurrency {
public float Convert<USD, EUR>(float from) {
return (from * 1.2f); }
public float Convert<EUR, USD>(float from) {
return (from / 1.2f); }
}
``````

``````class USD : ICurrency {
public float Convert<C1,C2>(float from) {
if (C1 is USD && C2 is EUR) {
}
}
}
``````

``````interface ICurrency {
float Convert(Type src, Type dest, float from);
}

class USD : ICurrency {
public float Convert(Type src, Type dest, float from) {
if (src.Name == "USD" && dest.Name == "EUR")
return from / 1.2f;
else if (src.Name == "EUR" && dest.Name == "USD")
return from * 1.2f;
else
throw new Exception("Illegal currency conversion");
}
}

class EUR : ICurrency {
public float Convert(Type src, Type dest, float from) {
if (src.Name == "USD" && dest.Name == "EUR")
return from / 1.2f;
else if (src.Name == "EUR" && dest.Name == "USD")
return from * 1.2f;
else
throw new Exception("Illegal currency conversion");
}
}

class Money<C> where C : ICurrency, new() {
public Money() { Currency = new C(); }
public Money(float amt) : this() { Quantity = amt; }

public float Quantity { get; set; }
public C Currency { get; set; }

public static Money<C> operator +(Money<C> lhs, Money<C> rhs) {
return new Money<C>(lhs.Quantity + rhs.Quantity);
}

public Money<C2> Convert<C2>() where C2 : ICurrency, new() {
return new Money<C2>(
Currency.Convert(typeof(C), typeof(C2), this.Quantity));
}
}
``````

## 动态语言与 动态编程

``````static class Conversions {
public static Money<EUR> USDToEUR(Money<USD> usd) {
return new Money<EUR>(usd.Quantity * 1.2f);
}

public static Money<USD> EURToUSD(Money<EUR> eur) {
return new Money<USD>(eur.Quantity / 1.2f);
}
}

class Money<C> where C : ICurrency, new() {
public Money() { Currency = new C(); }
public Money(float amt) : this() { Quantity = amt; }

public float Quantity { get; set; }
public C Currency { get; set; }

public static Money<C> operator +(Money<C> lhs, Money<C> rhs) {
return new Money<C>(lhs.Quantity + rhs.Quantity);
}

public Money<C2> Convert<C2>() where C2 : ICurrency, new() {
MethodBase converter = typeof(Conversions).GetMethod(
typeof(C).Name + "To" + typeof(C2).Name);
return (Money<C2>)converter.Invoke(null, new object[] { this });
}
}
``````

## 创建通用性

Ted Neward是 Neward & Associates 的负责人，这是一家专门研究企业 .NET Framework 系统和 Java 平台系统的独立公司。他曾写过 100 多篇文章，是 C# 领域最优秀的专家之一；他是 INETA 发言人；著有并合著过十几本书，包括《Professional F# 2.0》（Wrox，2010 年）。他定期担任顾问和导师，请通过 ted@tedneward.com 与他联系，或通过 blogs.tedneward.com 访问其博客。