2014-02-20 4 views
5

Я копирую ситуацию, с которой я столкнулся..ctor неоднозначно, потому что в классе есть несколько типов членов с таким именем

Допустим, у нас есть собрание, с C класса # как:

public class Program 
{ 
    int n = 0; 

    public void Print() 
    { 
     Console.WriteLine(n); 
    } 

    public Program() 
    { 
    } 

    public Program(int num = 10) 
    { 
     n = num; 
    } 
} 

Мы отсылаем выше сборки в проекте VB.NET и пытается создать экземпляр класса Program:

Module Module1 
    Sub Main() 
     Dim p As New Program() 
     p.Print() 
     p = New Program(20) 
     p.Print() 
     Console.ReadLine() 
    End Sub 
End Module 

Проект VB.NET не компилируется, давая ошибку:

«.ctor» неоднозначно, поскольку в классе «Conso» существует несколько видов членов с таким именем leApplication2.Program.

Из сообщения об ошибке мы можем видеть, что компилятор VB.NET не уверен, какой конструктор вызывать - поскольку один конструктор без параметров и другой с одним необязательным параметром. Эта проблема возникает в VS2010/.NET 4, а не в VS2012/.NET 4.5. Также в C# он не вызывает никаких проблем, он успешно компилирует и запускает код инициализации объекта класса Program.

Есть ли способ создать экземпляр класса программы в VB.NET + VS2010/.NET 4 без изменения конструкторов?

+2

Почему вы хотите эту конструкцию?Есть ли способ, который мне не хватает, что вы действительно можете вызвать второй конструктор и использовать компилятор по умолчанию? –

+0

Этот код пахнет. Это амбициозно без 'VB'. Как вы думаете, значение 'num' должно использоваться для использования как var program = new Program()'? Вы * факультативно * хотите 'num' быть' 10' или это конструктор по умолчанию, где 'num' is * field initialized * является' 0' ??? – Sinatr

+0

@Sinatr, это репликация ситуации, с которой я столкнулся. Я написал это так, чтобы я мог различать вывод и определять, какой конструктор вызывался на C#. – Brij

ответ

8

Проблема с определениями ваших конструкторов в Program класса

Поскольку аргумент второй является необязательным, то оба являются кандидатами при вызове с помощью New Program(). Это создает двусмысленность.

Вместо определять конструкторы, используя этот вид шаблона:

public Program() 
    : this(10) 
{ 
} 

public Program(int num) 
{ 
    n = num; 
} 

или только один конструктор:

public Program(int num = 10) 
{ 
    n = num; 
} 

(Лично я предпочитаю первый из них).

+0

@Jon_Egerton изменение конструктора будет сортировать проблему, но можно ли вызвать конкретный конструктор без внесения каких-либо изменений в класс C# 'Program'? Кроме того, двусмысленность не встречается в C#, но встречается в VB.NET. Также в VB.NET это происходит в .NET 4.0, а не .NET 4.5 – Brij

+0

Честно говоря, не уверен - у меня до сих пор возникают недочеты, или через некоторое время начинаются ошибки. Однако посмотрите на это по-другому. Когда вы вызываете «Новая программа()», что вы ожидаете от 'n'? - 0 или 10? Они не просто двусмысленны на уровне кода, но и на «условном» уровне. –

+0

Когда вы говорите .Net 4, это было в VS2010 или VS2012/13? –

0

Лучшим способом было бы изменить реализацию конструктора так же, как и @JonEgerton. Если это не представляется возможным, вы можете попробовать следующее - на самом деле не красивые - обходные пути:

  • Если вы знаете внутреннюю реализацию класса Program, вы можете просто вызвать конструктор с ИНТ-параметра со значением, что конструктор без параметров присваивает в вашем примере Dim p As New Program(0). Это подразумевает, что вам нужно быть осторожным в отношении последующих изменений в реализации конструкторов класса Program, поскольку они не будут отражены в вашей реализации. Например, если разработчики класса Program изменяют значение, назначенное в конструкторе без параметров, ваше решение по-прежнему будет назначать значение 0.
  • Поскольку C#, похоже, обрабатывает создание по-разному, вы также можете добавить класс C# (например, в библиотеке классов C#), которая создает экземпляр программы для вас и возвращает ее в ваш код. Хотя это, возможно, означает добавить библиотеку классов к вашему решению для этой единственной цели, и поэтому это не очень красивый подход, последующие изменения в реализации класса Program также будут отражены в вашей программе.