首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何对两个相似的COM对象重用代码?

如何对两个相似的COM对象重用代码?
EN

Stack Overflow用户
提问于 2018-09-04 17:14:08
回答 1查看 80关注 0票数 1

我正在处理来自两个COM组件的两个对象,但是它们基本上是相同的,只是方法不同,几乎没有什么不同(但从技术上讲,它们是不同的类)

假设我要处理的是object ab

代码语言:javascript
复制
var app = Marshal.GetActiveObject("MotherClassOfA&B");
NamespaceA.A a = app.OpenAsA("random-filepath") ;
NamespaceB.B b = app.OpenAsB("random-filepath") ;

我想访问一些也可以从b获得的a成员,但它们仍然是不同的类

代码语言:javascript
复制
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
}

虽然它们具有相同的名称,atypeof target.member1NamespaceA.someClassA,而btypeof target.member1NamespaceB.someClassB,但它们具有相同的名称(对于大多数成员)

问:DoWorkADoWorkB几乎是一样的,有没有可能为ab编写一个通用的方法DoWork

附注:我尝试过DoWork<T>(T target) where T:A,B,但它无法构建,因为Visual Studio无法分辨target.member1是在调用someClassA还是someClassB

Error member1NamespaceA.someClassA.member1NamespaceB.someClassB .member1之间的模糊引用

对于任何想知道的人来说,具体来说,他们是:

aAutoCAD.AcadDocumentbAXDBLib.AxDbDocument

并且没有任何类或接口IDocument可以使a is IDocumentb is IDocument同时成为true

EN

回答 1

Stack Overflow用户

发布于 2018-09-07 08:42:06

响应your comment并在@JeroenMostert's suggestion上构建,您可以为所有方法使用一个接口,或者为每个方法使用一个接口,或者根据需要使用介于两者之间的任何接口。让我们为所有方法创建一个...

代码语言:javascript
复制
interface IDocumentAdapter
{
    bool Member1
    {
        get; set;
    }

    int Member2
    {
        get; set;
    }

    string Member3
    {
        get; set;
    }
}

对于您正在适应的每个类型,您需要一个实现此接口的类,并包装一个对已适应类型的实例的引用……

代码语言:javascript
复制
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()方法...

代码语言:javascript
复制
public void DoWork(IDocumentAdapter documentAdapter)
{
    DealWith(documentAdapter.Member1);
    Check(documentAdapter.Member2);
    BlahBlah(documentAdapter.Member3);
}

或者,您可以简单地编写一个接受dynamic参数的DoWork()方法……

代码语言:javascript
复制
public void DoWork(dynamic target)
{
    DealWith(target.member1);
    Check(target.member2);
    BlahBlah(target.member3);
}

正如您所说,这样做的优点是不必为成百上千的成员编写适配器代码,但缺点是在使用dynamic变量时,您将得不到任何编译器/智能提示帮助,因为成员访问直到运行时才会被计算/检查/绑定。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52162830

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档