我正在处理来自两个COM组件的两个对象,但是它们基本上是相同的,只是方法不同,几乎没有什么不同(但从技术上讲,它们是不同的类)
假设我要处理的是object a
和b
:
var app = Marshal.GetActiveObject("MotherClassOfA&B");
NamespaceA.A a = app.OpenAsA("random-filepath") ;
NamespaceB.B b = app.OpenAsB("random-filepath") ;
我想访问一些也可以从b
获得的a
成员,但它们仍然是不同的类
public void DoWorkA(NamespaceA.A target){
DealWith(target.member1);
Check(target.member2);
BlahBlah(target.member3);
... // many others
}
public void DoWorkB(NamespaceB.B target){
DealWith(target.member1);
Check(target.member2);
BlahBlah(target.member3);
... // many others same as DoWorkA
}
虽然它们具有相同的名称,a
的typeof target.member1
是NamespaceA.someClassA
,而b
的typeof target.member1
是NamespaceB.someClassB
,但它们具有相同的名称(对于大多数成员)
问:DoWorkA
和DoWorkB
几乎是一样的,有没有可能为a
和b
编写一个通用的方法DoWork
附注:我尝试过DoWork<T>(T target) where T:A,B
,但它无法构建,因为Visual Studio无法分辨target.member1
是在调用someClassA
还是someClassB
Error
member1
是NamespaceA.someClassA.member1
和NamespaceB.someClassB .member1
之间的模糊引用
对于任何想知道的人来说,具体来说,他们是:
a
为AutoCAD.AcadDocument
,b
为AXDBLib.AxDbDocument
并且没有任何类或接口IDocument
可以使a is IDocument
和b is IDocument
同时成为true
发布于 2018-09-07 08:42:06
响应your comment并在@JeroenMostert's suggestion上构建,您可以为所有方法使用一个接口,或者为每个方法使用一个接口,或者根据需要使用介于两者之间的任何接口。让我们为所有方法创建一个...
interface IDocumentAdapter
{
bool Member1
{
get; set;
}
int Member2
{
get; set;
}
string Member3
{
get; set;
}
}
对于您正在适应的每个类型,您需要一个实现此接口的类,并包装一个对已适应类型的实例的引用……
class AcadDocumentAdapter : IDocumentAdapter
{
public AcadDocumentAdapter(AutoCAD.AcadDocument document)
{
Document = document;
}
private AutoCAD.AcadDocument Document
{
get;
}
public bool Member1
{
get => Document.Member1;
set => Document.Member1 = value;
}
public int Member2
{
get => Document.Member2;
set => Document.Member2 = value;
}
public string Member3
{
get => Document.Member3;
set => Document.Member3 = value;
}
}
class AxDbDocumentAdapter : IDocumentAdapter
{
public AxDbDocumentAdapter(AXDBLib.AxDbDocument document)
{
Document = document;
}
private AXDBLib.AxDbDocument Document
{
get;
}
public bool Member1
{
get => Document.Member1;
set => Document.Member1 = value;
}
public int Member2
{
get => Document.Member2;
set => Document.Member2 = value;
}
public string Member3
{
get => Document.Member3;
set => Document.Member3 = value;
}
}
然后,您只需要一个通过IDocumentAdapter
接口执行其逻辑的DoWork()
方法...
public void DoWork(IDocumentAdapter documentAdapter)
{
DealWith(documentAdapter.Member1);
Check(documentAdapter.Member2);
BlahBlah(documentAdapter.Member3);
}
或者,您可以简单地编写一个接受dynamic
参数的DoWork()
方法……
public void DoWork(dynamic target)
{
DealWith(target.member1);
Check(target.member2);
BlahBlah(target.member3);
}
正如您所说,这样做的优点是不必为成百上千的成员编写适配器代码,但缺点是在使用dynamic
变量时,您将得不到任何编译器/智能提示帮助,因为成员访问直到运行时才会被计算/检查/绑定。
https://stackoverflow.com/questions/52162830
复制相似问题