C# 使用相同的对象是个坏主意,方法调用后会产生不同的副作用

C# 使用相同的对象是个坏主意,方法调用后会产生不同的副作用,c#,com,wrapper,C#,Com,Wrapper,我(又一次)遇到了一个小问题。假设我有这个Buttonpad对象: 现在,这个对象是com对象中一个上的包装器对象。目前,它有一个名为CreateInto(IComObject)的方法。现在在Com对象中创建一个新的按钮板 你可以: ButtonPad pad = new ButtonPad(); pad.Title = "Hello"; // Set some more properties. pad.CreateInto(Cominstance); createinfo方法将

我(又一次)遇到了一个小问题。假设我有这个Buttonpad对象:

现在,这个对象是com对象中一个上的包装器对象。目前,它有一个名为CreateInto(IComObject)的方法。现在在Com对象中创建一个新的按钮板

你可以:

 ButtonPad pad =  new ButtonPad();
 pad.Title =  "Hello";
 // Set some more properties.
 pad.CreateInto(Cominstance);
createinfo方法将执行在com对象中构建按钮板的正确命令。创建后,对其进行的任何调用都将转发给基础对象进行更改,以便:

pad.Title = "New title";
将调用com对象来设置标题,还将设置内部标题变量

基本上,CreateInfo方法之前的任何调用都只会影响.NET对象,之后的任何调用都会产生调用com对象的副作用。我不太擅长序列图,但以下是我试图解释发生了什么:

这让我感觉不好,我觉得我在对用户撒谎,说的是按钮板的功能

我本来打算有一个名为WrappedButtonPad的对象,它是从CreateInto返回的,用户可以调用它来更改Com对象,但我觉得有两个几乎做相同事情但名称不同的对象可能更糟糕

这些设计是有效的,还是我担心是对的


否则,您将如何处理一个可以创建和查询com对象的对象?

我将允许ButtonPad创建自己的ComInstance。我在序列图中注意到,ButtonPad是唯一接触ComInstance的对象。所以请把它放在内部。

我同意约翰的回答

另一种选择是在实例化ButtonPad时将其内部状态复制到COM对象

ie:选项1(John的)是从ButtonPad构造函数创建COM对象

选项2是将ButtonPad的状态反映到ButtonPad.CreatePad(…)中的COM对象。CreatePad(…)然后将在COM对象上调用CreateButtonPad,然后在返回之前在COM对象上调用SetTitle()等,以便ButtonPad确保COM对象的状态一致


如果ButtonPad在没有COM对象的情况下存在是有意义的,或者如果在实例化ButtonPad时您没有访问实例化COM对象所需的IComObject的权限,我更喜欢选项2。否则我会选择选项1。

我首先会问:独立于隐藏的底层属性操作
按钮ad
属性的用例是什么?对此,最有可能有两个答案:1)没有一个答案,2)我们能够做到这一点至关重要

第一种情况下的答案非常简单:在类的构造函数中创建底层COM对象,将属性映射到它的属性上,然后结束调用

不过,在第二种情况下,您进入了一个闻起来很像数据绑定的领域。您有一个数据源(您的对象),它绑定到的对象(COM对象),需要在这两个对象之间转换属性值(即,如果通信是双向的,则解析和格式化),甚至可能需要通过事件通知映射属性更改。(例如,如果有其他操作COM对象的属性,是否需要通知您的.NET对象?)

我并不是说您真的想使用绑定来实现这一点,但我肯定会看看.NET数据绑定的设计方式,看看您实际需要多少设计


很可能,你会看着它说“哇,这真的很复杂。”这是因为你要做的基本上是非常复杂的。如果您的设计没有实现关注点分离,那么问题会复杂得多。

我的库中有更多的对象,而我的库中只有按钮板,因此我将其传入。它们都使用相同的ComInstance?是的。我正在为一个映射程序制作一个.NET SDK,该程序只向方法公开一个获取字符串,一个获取字符串,并返回结果作为“猜什么是字符串”:(因此,我在基于过程脚本的程序的顶部制作一个OO包装。那么,什么是ComInstance-映射程序?是的。用户创建实例,然后将其传递到每个包装层。