C#编译器错误还是正常的COM异常?
C#4,为了简化COM互操作,允许COM接口的调用方在by ref参数的参数前面省略ref关键字 今天我很惊讶地看到,这也适用于扩展COM接口的扩展方法。请参阅下面的编译代码:C#编译器错误还是正常的COM异常?,c#,c#-4.0,compiler-construction,csc,C#,C# 4.0,Compiler Construction,Csc,C#4,为了简化COM互操作,允许COM接口的调用方在by ref参数的参数前面省略ref关键字 今天我很惊讶地看到,这也适用于扩展COM接口的扩展方法。请参阅下面的编译代码: using System; using System.Runtime.InteropServices; [ComImport, Guid ("cb4ac859-0589-483e-934d-b27845d5fe74")] interface IFoo { } static class Program { p
using System;
using System.Runtime.InteropServices;
[ComImport, Guid ("cb4ac859-0589-483e-934d-b27845d5fe74")]
interface IFoo {
}
static class Program {
public static void Bar (this IFoo self, ref Guid id)
{
id = Guid.NewGuid ();
}
static void Main ()
{
Foo (null);
}
static void Foo (IFoo o)
{
Guid g = Guid.NewGuid ();
Console.WriteLine (g);
// note that g is passed as is, and not as ref g
o.Bar (g);
Console.WriteLine (g);
}
}
我在规范中没有找到任何东西来解释这种行为
我的感觉是,COM接口之外的代码,即使是扩展COM接口的扩展方法,也应该遵循常规的C#规则,并强制使用ref关键字。因此,我提交了一份报告。我并不认为这会被修复,即使它被认为是一个bug,已经有代码依赖于此
臭虫?不是虫子吗?我不认为它是虫子;它看起来更像你说的“COM巫毒”。在引擎盖下,C#编译器发出一些事实上正确的东西,比如:
private static void Foo(IFoo o)
{
...
Guid g = Guid.NewGuid();
Guid <>r__ComRefCallLocal0 = g;
Bar(o, ref <>r__ComRefCallLocal0);
...
}
同样,您可以在C#4中声明:
当然,所有这些都只起作用,因为CSC.EXE非常熟悉ComImport属性。这些新的互操作魔术被添加到C#4.0中,以便能够轻松地与现有COM接口进行互操作。嗯,对于Microsoft Office界面和方法来说,尤其是那些可怕的“ref-missing”参数:-)
我认为这并没有在任何地方得到充分的说明。这就是C#4规范的全部内容:
17.5互操作属性注意:本节仅适用于C#的Microsoft.NET实现。
17.5.1与COM和Win32组件的互操作.NET运行时提供了大量属性,使C#程序能够
与使用COM和Win32 DLL编写的组件进行互操作。对于
例如,DllImport属性可用于静态外部方法
指示该方法的实现将在
Win32 DLL。这些属性可以在
System.Runtime.InteropServices命名空间和详细文档
有关这些属性的详细信息,请参见.NET运行时文档
以下是有关MSDN的一些页面:
[ComImport, Guid("cb4ac859-0589-483e-934d-b27845d5fe74")]
interface IFoo
{
void Test([Optional] ref object test);
}
static void Foo(IFoo o)
{
Guid g = Guid.NewGuid();
o.Test(g);
}