问题描述
昨天我们队的球员2来找我用一种不常见的问题。我们在我们的的WinForms应用程序之一使用第三方组件。所有的代码已被写入反对。然后,他们希望融入其他第三方组件,由同一厂商,为我们的应用程序。他们的喜悦,他们发现,第二部分有完全相同的公共成员为第一。但他们沮丧的是,2组件具有完全独立的继承层次,并实现不常用接口。 。让你不知道...好吧,让我怀疑
Yesterday 2 of the guys on our team came to me with an uncommon problem. We are using a third-party component in one of our winforms applications. All the code has already been written against it. They then wanted to incorporate another third-party component, by the same vender, into our application. To their delight they found that the second component had the exact same public members as the first. But to their dismay, the 2 components have completely separate inheritance hierarchies, and implement no common interfaces. Makes you wonder... Well, makes me wonder.
问题的一个例子:
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.");
}
}
欣然他们感到复制和粘贴他们的写的代码第一组分是不正确的答案。所以他们想分配组件瞬间化为一个对象引用,然后修改代码检查它是什么类型后做有条件的铸件。但是,这可以说是比复制和粘贴的方式,甚至丑陋。
Gladly they felt copying and pasting the code they wrote for the first component was not the correct answer. So they were thinking of assigning the component instant into an object reference and then modifying the code to do conditional casts after checking what type it was. But that is arguably even uglier than the copy and paste approach.
因此,他们然后问我,如果我可以写一些反射代码访问的属性和取消的方法因为我们两个不同的对象类型知道它们是什么,他们是完全一样的。但我的第一个念头是有云的风采。我想,必须有一个更好的,优雅的解决了这个问题。
So they then asked me if I can write some reflection code to access the properties and call the methods off the two different object types since we know what they are, and they are exactly the same. But my first thought was that there goes the elegance. I figure there has to be a better, graceful solution to this problem.
推荐答案
我的第一个问题是,是2三阶党的组件类封了?他们不是。 。至少我们有
My first question was, are the 2 third-party component classes sealed? They were not. At least we have that.
所以,因为它们是不密封的,问题是通过以下方式可解
So, since they are not sealed, the problem is solvable in the following way:
提取的通用接口出2第三方类的一致成员。我把它叫做Icommon。
Extract a common interface out of the coinciding members of the 2 third-party classes. I called it Icommon.
public interface ICommon
{
string Name
{
get;
}
void DoThirdPartyStuff ();
}
然后创建2个新的类别; DerivedClass1和DerivedClass2从ThirdPartyClass1和ThirdPartyClass2分别继承。 。这2个新的类都实现了ICommon接口,但在其他方面完全是空的。
Then create 2 new classes; DerivedClass1 and DerivedClass2 that inherit from ThirdPartyClass1 and ThirdPartyClass2 respectively. These 2 new classes both implement the ICommon interface, but are otherwise completely empty.
public class DerivedClass1
: ThirdPartyClass1, ICommon
{
}
public class DerivedClass2
: ThirdPartyClass2, ICommon
{
}
现在,尽管所导出的类是空的,接口是由基类满意,这是我们从首先提取的接口。
生成的类图看起来是这样的。
Now, even though the derived classes are empty, the interface is satisfied by the base classes, which is where we extracted the interface from in the first place.The resulting class diagram looks like this.
所以,现在,而不是我们以前有:
So now, instead of what we previously had:
ThirdPartyClass1 c1 = new ThirdPartyClass1 ();
c1. DoThirdPartyStuff ();
我们现在可以做的:
ICommon common = new DerivedClass1 ();
common. DoThirdPartyStuff ();
和同样可以用DerivedClass2完成。
And the same can be done with DerivedClass2.
的结果是,引用ThirdPartyClass1的一个实例,我们所有的现有代码可以为左,只需换出一个ICommon参考ThirdPartyClass1参考。然后ICommon参考可以给予DerivedClass1或DerivedClass2,这当然反过来从ThirdPartyClass1和ThirdPartyClass2分别继承的一个实例。和所有的只是工作。
The result is that all our existing code that referenced an instance of ThirdPartyClass1 can be left as is, by just swapping out the ThirdPartyClass1 reference for a ICommon reference. The ICommon reference could then be given an instance of DerivedClass1 or DerivedClass2, which of course in turn inherits from ThirdPartyClass1 and ThirdPartyClass2 respectively. And all just works.
我不知道是否有这一个特定的名字,但对我来说,它看起来像适配器模式的一个变种。
I do not know if there is a specific name for this, but to me it looks like a variant of the adaptor pattern.
也许我们可以有解决动态类型在C#4.0中的问题,但是这还没有编译时检查的好处。
Perhaps we could have solve the problem with the dynamic types in C# 4.0, but that would have not had the benefit of compile-time checking.
我会非常有兴趣知道,如果任何人有解决这个问题的另一种优雅的方式。
I would be very interested to know if anybody else has another elegant way of solving this problem.
这篇关于如何使2不兼容的类型,但具有相同的部件,可互换?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!