Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/jsf/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
COM接口中的C#数组属性?_C#_Arrays_Properties_Interface_Com - Fatal编程技术网

COM接口中的C#数组属性?

COM接口中的C#数组属性?,c#,arrays,properties,interface,com,C#,Arrays,Properties,Interface,Com,我正在使用C#重写一个以前在Delphi中使用的应用程序。它必须提供进程外COM服务器,该服务器具有与Delphi实现完全相同的接口。 COM服务器的Delphi实现利用了使用字符串作为索引的数组属性。 COM客户端(主要用VBA编写)通过以下方式访问阵列属性: X = Obj.Member(“FirstName”) // get Obj.Member(“FirstName”) = “John” // put 不可能更改这些调用的语法 我现在的问题是: 如

我正在使用C#重写一个以前在Delphi中使用的应用程序。它必须提供进程外COM服务器,该服务器具有与Delphi实现完全相同的接口。 COM服务器的Delphi实现利用了使用字符串作为索引的数组属性。 COM客户端(主要用VBA编写)通过以下方式访问阵列属性:

X = Obj.Member(“FirstName”)             // get
Obj.Member(“FirstName”) = “John”        // put
不可能更改这些调用的语法

我现在的问题是:

如何在C#接口(COM)中实现数组属性? 更多信息:

我尝试在C#中实现一个索引属性
,这适用于CoClass,但我没有找到任何方法将其嵌入到接口中(因为不允许任何字段),对于COM接口,我需要使用接口

TypeLibrary文件(.tlb)可用,并且为Delphi数组属性生成的IDL代码如下所示:

[id(0x00000001), propget]
VARIANT Member([in] VARIANT Index);
[id(0x00000001), propput]
void Member(
              [in] VARIANT Index,
              [in] VARIANT rhs);
[DispId(1)] (…CLR Stuff…)
object get_Member([MarshalAs(UnmanagedType.Struct), In] object Index);
[DispId(1)] (…CLR Stuff…)
void set_Member([MarshalAs(UnmanagedType.Struct), In] object Index, [MarshalAs(UnmanagedType.Struct), In] object Value);
因此,似乎主要是将数组属性转换为具有相同ID的两个不同方法,一个具有属性propget,另一个具有属性propput。 据我所知,在C#中手动设置这些属性是不可能的。 在现有TLB上使用tlbimp.exe,所创建DLL的反汇编如下所示:

[id(0x00000001), propget]
VARIANT Member([in] VARIANT Index);
[id(0x00000001), propput]
void Member(
              [in] VARIANT Index,
              [in] VARIANT rhs);
[DispId(1)] (…CLR Stuff…)
object get_Member([MarshalAs(UnmanagedType.Struct), In] object Index);
[DispId(1)] (…CLR Stuff…)
void set_Member([MarshalAs(UnmanagedType.Struct), In] object Index, [MarshalAs(UnmanagedType.Struct), In] object Value);
我尝试实现类似的结构(相同的DispID)。 但是,使用regasm.exe/tlb时,方法ID在生成的tlb中不同。此外,我无法使用Obj.Member访问方法

我还尝试给这些方法赋予相同的名称和DispID。这对Get有效,但对put无效

一般来说,我甚至不需要类型库。我很高兴COM客户端能够以指定的方式访问COM服务器


你知道如何在C#接口(COM)中实现数组属性吗?

我曾尝试在C#中实现索引属性,这对于CoClass是可行的,但我没有找到任何方法可以将其嵌入接口中
这里有什么问题?您当然可以在接口中包含索引器。类似于:
int这个[string val]{get;set;}
在接口中应该可以。谢谢您的回答。是的,如果我想以
Obj(“key”)=“somevalue”
的形式访问对象,这将很好,但是因为我需要访问
Obj.Member(“key”)=“somevalue”
,所以成员需要是接口的一个字段。这在C#中似乎是不可能的。或者我理解错了什么?那么无论
Member
是什么类型,都需要一个索引器。我试过创建一个类,让我们称之为MemberClass。它使用一个索引属性,如果在另一个类中用作字段(可由
OtherClass.Member[“index”]调用),它的工作方式与我所需要的完全相同
…但是,似乎不可能在COM接口中将MemberClass用作字段,因为接口不能有字段。这是C#中的一个众所周知的限制。使用VB.NET声明接口或继续使用原始类型库。后者是一种聪明的方法,您不能以这种方式破坏现有的客户端代码。