- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
昨天,我们团队中的两个人带着一个不常见的问题来找我。我们在我们的一个 winforms 应用程序中使用第三方组件。所有的代码都是针对它编写的。然后他们想将同一供应商的另一个第三方组件合并到我们的应用程序中。令他们高兴的是,他们发现第二个组件与第一个组件具有完全相同的公共(public)成员。但令他们沮丧的是,这两个组件具有完全独立的继承层次结构,并且没有实现公共(public)接口(interface)。让你想知道……好吧,让我想知道。
问题示例:
Incompatible Types http://www.freeimagehosting.net/uploads/f9f6b862f1.png
public class ThirdPartyClass1
{
public string Name
{
get
{
return "ThirdPartyClass1";
}
}
public void DoThirdPartyStuff ()
{
Console.WriteLine ("ThirdPartyClass1 is doing its thing.");
}
}
public class ThirdPartyClass2
{
public string Name
{
get
{
return "ThirdPartyClass2";
}
}
public void DoThirdPartyStuff ()
{
Console.WriteLine ("ThirdPartyClass2 is doing its thing.");
}
}
很高兴他们觉得复制和粘贴他们为第一个组件编写的代码不是正确的答案。因此,他们考虑将组件 instant 分配给一个对象引用,然后在检查它是什么类型后修改代码以进行条件转换。但这可以说比复制和粘贴方法更丑陋。
然后他们问我是否可以编写一些反射代码来访问属性并调用两种不同对象类型的方法,因为我们知道它们是什么,而且它们完全相同。但我的第一个想法是优雅消失了。我认为必须有一个更好、更优雅的解决方案来解决这个问题。
最佳答案
我的第一个问题是,这2个第三方组件类是密封的吗?他们不是。至少我们有。
因此,由于它们不是密封的,因此可以通过以下方式解决问题:
从 2 个第三方类的重合成员中提取一个公共(public)接口(interface)。我称它为 Icommon。
public interface ICommon
{
string Name
{
get;
}
void DoThirdPartyStuff ();
}
然后新建2个类; DerivedClass1 和 DerivedClass2 分别继承自 ThirdPartyClass1 和 ThirdPartyClass2。这 2 个新类都实现了 ICommon 接口(interface),但在其他方面完全是空的。
public class DerivedClass1
: ThirdPartyClass1, ICommon
{
}
public class DerivedClass2
: ThirdPartyClass2, ICommon
{
}
现在,即使派生类是空的,接口(interface)也由基类满足,这是我们首先从中提取接口(interface)的地方。生成的类图如下所示。
alt text http://www.freeimagehosting.net/uploads/988cadf318.png
所以现在,而不是我们以前拥有的:
ThirdPartyClass1 c1 = new ThirdPartyClass1 ();
c1. DoThirdPartyStuff ();
我们现在可以:
ICommon common = new DerivedClass1 ();
common. DoThirdPartyStuff ();
同样可以用 DerivedClass2 完成。
结果是我们所有引用 ThirdPartyClass1 实例的现有代码都可以保留原样,只需将 ThirdPartyClass1 引用换成 ICommon 引用即可。然后可以为 ICommon 引用提供 DerivedClass1 或 DerivedClass2 的实例,这当然又分别继承自 ThirdPartyClass1 和 ThirdPartyClass2。一切正常。
我不知道是否有具体名称,但对我来说它看起来像是适配器模式的变体。
也许我们可以用 C# 4.0 中的动态类型来解决这个问题,但是那将没有编译时检查的好处。
我很想知道是否有人有另一种优雅的方法来解决这个问题。
关于c# - 如何使 2 个不兼容的类型,但具有相同的成员,可互换?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2475920/
有谁知道 double 是否隐式转换为 double? (Nullable 类型) 编辑:这里究竟发生了什么? double d = 5; double? d2 = d as double? 最佳答案
我是 Java 的新手,现在我一直在努力解决以下问题。 我的项目中有“人类”这个类,作为我模型的一部分,我希望我的人类能够特化,从而拥有新的行为。例如,我可以让一个人开始时是“平民”,但后来可以变成“
ES2015中的箭头函数提供了更简洁的语法。 我现在可以用箭头函数替换所有函数声明/表达式吗? 我要注意什么? 例子: 构造函数 function User(name) { this.name =
ES2015中的箭头函数提供了更简洁的语法。 我现在可以用箭头函数替换所有函数声明/表达式吗? 我要注意什么? 例子: 构造函数 function User(name) { this.name =
ES2015中的箭头函数提供了更简洁的语法。 我现在可以用箭头函数替换所有函数声明/表达式吗? 我要注意什么? 例子: 构造函数 function User(name) { this.name =
ES2015中的箭头函数提供了更简洁的语法。 我现在可以用箭头函数替换所有函数声明/表达式吗? 我要注意什么? 例子: 构造函数 function User(name) { this.name =
ES2015中的箭头函数提供了更简洁的语法。 我现在可以用箭头函数替换所有函数声明/表达式吗? 我要注意什么? 例子: 构造函数 function User(name) { this.name =
ES2015中的箭头函数提供了更简洁的语法。 我现在可以用箭头函数替换所有函数声明/表达式吗? 我要注意什么? 例子: 构造函数 function User(name) { this.name =
ES2015中的箭头函数提供了更简洁的语法。 我现在可以用箭头函数替换所有函数声明/表达式吗? 我要注意什么? 例子: 构造函数 function User(name) { this.name =
ES2015中的箭头函数提供了更简洁的语法。 现在可以用箭头函数替换所有函数声明/表达式吗? 我要注意什么? 示例: 构造函数 function User(name) { this.name =
ES2015中的箭头函数提供了更简洁的语法。 我现在可以用箭头函数替换所有函数声明/表达式吗? 我要注意什么? 例子: 构造函数 function User(name) { this.name =
ES2015中的箭头函数提供了更简洁的语法。 我现在可以用箭头函数替换所有函数声明/表达式吗? 我要注意什么? 例子: 构造函数 function User(name) { this.name =
ES2015中的箭头函数提供了更简洁的语法。 我现在可以用箭头函数替换所有函数声明/表达式吗? 我要注意什么? 例子: 构造函数 function User(name) { this.name =
昨天,我们团队中的两个人带着一个不常见的问题来找我。我们在我们的一个 winforms 应用程序中使用第三方组件。所有的代码都是针对它编写的。然后他们想将同一供应商的另一个第三方组件合并到我们的应用程
ES2015 中的箭头函数提供了更简洁的语法。 我现在可以用箭头函数替换我所有的函数声明/表达式吗? 我需要注意什么? 例子: 构造函数 function User(name) { this.na
我的目标是编写一个 Model.find_by_name("foo-bar"),将在数据库中返回一条名为“foo bar”的记录。我正在努力寻找有关如何实现这一点的任何信息。我正在使用 postgre
我是一名优秀的程序员,十分优秀!