Почему конструктор ORDER имеет значение в VB.Net? Я создаю библиотеку типов .Net, которая должна полностью обернуть лежащую в основе библиотеку COM, чтобы потребители API могли притворяться, что используют красивую библиотеку .Net с коллекциями .Net и еще много чего вместо библиотеки COM.
В настоящее время большинство моих классов - это просто обёртки от 1 до 1, построенные с использованием Reflection и CodeDOM. Эти классы имеют внутренний конструктор, который принимает базовый тип COM в качестве параметра. CodeDOM строит это как первый конструктор класса. Использование этих классов из C # не вызывает проблем. Все, что мне нужно, это ссылка на библиотеку .Net, и все работает хорошо.
Проблемы возникают, когда я пытаюсь использовать эти классы из проекта VB.Net. Если первый конструктор имеет тип COM в качестве аргумента, проект VB.Net требует сборки взаимодействия COM в качестве ссылки. Если первый конструктор не имеет аргументов или имеет только управляемые типы, все работает хорошо. Моя библиотека классов написана на C #.
Следующие работы:
public class ObjectID
{
public ObjectID(int type, int id)
{
this.Type = type;
this.ID = id;
}
internal ObjectID(COMLib.ObjectID id) : this(id.Type, id.ID) { }
public int ID { get; set; }
public int Type { get; set; }
internal COMLib.ObjectID ToCOM()
{
COMLib.ObjectID id = new COMLib.ObjectID();
id.ID = this.ID;
id.Type = this.Type;
return id;
}
}
Следующее требует ссылки на сборку COMLib.Interop:
public class ObjectID
{
internal ObjectID(COMLib.ObjectID id) : this(id.Type, id.ID) { }
public ObjectID(int type, int id)
{
this.Type = type;
this.ID = id;
}
public int ID { get; set; }
public int Type { get; set; }
internal COMLib.ObjectID ToCOM()
{
COMLib.ObjectID id = new COMLib.ObjectID();
id.ID = this.ID;
id.Type = this.Type;
return id;
}
}
Теперь я могу решить эту проблему, создав фиктивный закрытый конструктор для этих классов в качестве первого конструктора, но мне более любопытно, с чем это связано? Почему порядок объявлений конструктора имеет значение в VB.Net?
Обновление
Это звучало настолько безумно, что я сам начал сомневаться в этом. Удалось воспроизвести его с 3 проектами.
Библиотека классов C #: Wrapped
namespace Wrapped
{
public class Class1
{
}
}
Библиотека классов C #: Wrapper
namespace Wrapper
{
public class Class1
{
internal Class1(Wrapped.Class1 c) { }
public Class1() { }
}
}
Консольное приложение VB.Net: Referer
Module Module1
Sub Main()
Dim w As New Wrapper.Class1
End Sub
End Module
Обертка относится к Wrapped
Реферер ссылается на Wrapper
Реферер НЕ ссылается на Wrapped
Dim w As New Wrapper.Class1
выдает ошибку
Reference required to assembly 'Wrapped, Version=1.0.0.0,
Culture=neutral,
PublicKeyToken=null'
containing the type 'Wrapped.Class1'.
Add one to your project.
Замена порядка конструкторов устраняет ошибку.
https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=442224
Обновление после дополнительной игры
Causes error: No error:
Vb-ReferTest Vb-RefererTest
| | Fixes error in Vb-
V V RefererTest even
Cs-Wrapper Cs-Wrapper Vb-Wrapper <- if the Vb-Wrapper
| \ / and the RefererTest
V V V have no direct
Cs-WrappedLibrary Cs-WrappedLibrary relationship