С# 4, чтобы упростить COM-взаимодействие, разрешить вызывающим абонентам COM-интерфейсам опускать ключевое слово ref перед аргументами по параметрам ref.
Я был удивлен, увидев сегодня, что это также относится к методам расширения, которые расширяют интерфейсы COM. См. Следующее, компиляция, код:
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-интерфейс, должен следовать обычным правилам С# и обеспечивать использование ключевого слова ref. Поэтому я подал сообщение об ошибке при подключении. Не то чтобы я думаю, что это будет исправлено, даже если оно будет считаться ошибкой, там уже есть код, полагающийся на это.
Bug? Не ошибка?