Наследование класса Visual Basic в C # и переопределение конструкторов, которые принимают необязательные параметры - PullRequest
0 голосов
/ 12 января 2010

Настройка

Большая часть нашей кодовой базы находится в VB.NET.Я разрабатываю проект на C #, который использует множество сборок из кода VB.NET.

В VB.NET есть три соответствующих класса:

Public MustInherit Class mdTable
    Public Sub New(ByVal sqlConnectionStr As String, Optional ByVal maxSecsToDisableConnection As Integer = 60)
         ReDim pConnStr(0)
         pConnStr(0) = sqlConnectionStr
         pDBName = parseDBName(sqlConnectionStr)
         m_colLastConnectStatus.disablePeriod = maxSecsToDisableConnection
    End Sub


Public MustInherit Class xsTable //uses the constructor above since second parameter is optional
Inherits mdTable
    Public Sub New(ByVal sqlConnectionString As String)
         MyBase.New(sqlConnectionString)
    End Sub


Public Class SharedCallsTable //the only constructor available in this class
Inherits xsTable
    Public Sub New(Optional ByRef lErrStr As String = "", _
               Optional ByVal checkTableExists As Boolean = False, _
               Optional ByVal sqlServerIndex As Integer = -1)
         MyBase.New(forceServerIndex:=sqlServerIndex)

         defineTable(DBUser, checkTableExists)
         lErrStr &= CStr(IIf(errStr <> "", vbCrLf & errStr, ""))
End Sub

Все этиочевидно, в Visual Basic.

Существует много различных версий SharedCallsTable, которые работают с другими типами таблиц в нашей базе данных SQL, SharedCallsTable - это всего лишь один пример.

Проблема:

Я не могу создать экземпляр SharedCallsTable с помощью конструктора xsTable, который принимает в качестве конструктора одну строку, поскольку он вызывает конструктор mdTable, который имеет необязательный параметр (maxSecsToDisableConnection).C # не поддерживает необязательные параметры.

Поэтому, когда я делаю это:

SharedCallsTable myTable = new SharedCallsTable(connectionString);

, я получаю

SharedCallsTable не содержит конструктор, который принимает '1'Аргументы

Прогресс до настоящего времени

Я создал другой класс, xsToolboxTable, в C #, который наследует xsTable и просто вызывает однострочный конструктор, например, так:

class xsToolboxTable : xsTable
{
    public xsToolboxTable(string connectionString) : base(connectionString)
    {

    }
}

Однако это означает, что я могу создавать только экземпляр xsTable, но не экземпляр SharedCallsTable, поскольку они оба наследуются от одного и того же класса.

Я также пытался заставить мой класс расширения наследовать от SharedCallsTable, но тогда это дает мне то же самое.

Я получаю

SharedCallsTable не содержит конструктор, который принимает аргументы '1'

Что я на самом деленужно сделать, это вызвать базу конструктора базового класса, то есть базой xsTableExtension является SharedCallsTable.Основой SharedCallsTable является xsTable, который имеет однострочный конструктор, который мне нужно использовать.

Я знаю, что это действительно запутанно, и может быть действительно простое решение, которое я просто полностью упускаю.

Это довольно сложно, поэтому, пожалуйста, потерпите меня.

Ответы [ 3 ]

8 голосов
/ 12 января 2010

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

SharedCallsTable myTable = new SharedCallsTable(connectionString, false, -1);

Необязательные параметры - это всего лишь хитрость компилятора, поэтому, если вы не предоставите значение для параметра, компилятор посмотрит, что является значением по умолчанию и предоставит вам. Таким образом, предоставляя значения, которые совпадают со значениями по умолчанию, вы будете наблюдать такое же поведение, как если бы поддерживаются необязательные параметры, и вы их опускали.


Edit:

ОК, из комментария, я думаю, что я неправильно понял ваш вопрос. Похоже, что вы просите, чтобы иметь возможность создать экземпляр SharedCallsTable с предоставленной пользователем строкой соединения, минуя его логику конструктора, как если бы у него был конструктор, который напрямую связан с конструктором базового класса. 1012 *

Вы не можете этого сделать, и на то есть веская причина. Конструкторы выполняют работу, чтобы получить объект в правильном состоянии, и вы не можете просто обойти эту логику, ожидая, что объект будет работать.

Если вы хотите иметь возможность предоставить строку соединения, вам нужно добавить конструктор к SharedCallsTable, который связывает базовый класс и гарантирует, что класс находится в приемлемом состоянии для использования.

2 голосов
/ 12 января 2010

Нет, вы не хотите вызывать «базу конструктора базового класса» - вы хотите вызывать конструктор базового класса как обычно, просто явно передавая все аргументы. Просто относитесь к нему как к методу, который не имеет никаких дополнительных параметров. Это верно как для вызова конструктора в другом месте, так и для цепочки:

SharedCallsTable myTable = new SharedCallsTable(connectionString, false, -1);

и вы можете получить из класса, как это, если вы хотите:

class xsTableExtension : xsTable
{
    public xsToolboxTable(string connectionString) : base(connectionString, 60)
    {
    }    
}

(Не наследуйте от класса только для вызова конструктора с некоторыми значениями по умолчанию.)

Обратите внимание, что C # 4.0 поддерживает дополнительные параметры между прочим, поэтому в конце туннеля есть свет.

0 голосов
/ 12 января 2010

Когда я делаю это, как предложено Джоном

class xsTableExtension : xsTable
{
    public xsToolboxTable(string connectionString) : base(connectionString, 60)
    {
    }
}

Я получаю ту же ошибку, что и раньше

xsTable не содержит конструктор, который принимает аргументы '2'

Мое решение (для дальнейшего использования) состоит в том, чтобы переопределить конструктор в классе прародителя mdTable, который не принимает необязательный параметр и просто принимает строку соединения.

До выхода C # 4.0 это не так.

...