Инициализация объекта - PullRequest
1 голос
/ 27 января 2011

У меня есть классы, подобные следующим:

Public Class Form1
    Private d As New Dings("dings")
End Class
Public Class Foo
    Public Sub New(ByVal aName As String)
        MsgBox("new Foo """ & aName & """")
    End Sub
End Class
Public Class Dings
    Public Property Name As String
    Public Property MyFoo As New Foo(Name)
    Public Sub New(ByVal aName As String)
        _Name = aName
    End Sub
End Class

Я хочу, чтобы свойство Name класса Dings было инициализировано сначала, но все наоборот, есть ли у вас идеи, как этого добиться??Я знаю, я мог бы также создать объект foo (как член dings) позже в конструкторе.Но я хочу, чтобы это было так, потому что, в конце концов, в классе Dings создается очень много одноэлементных объектов, которые я хочу создать только в одной строке.С уважением

####### EDIT #############

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

Ответы [ 3 ]

4 голосов
/ 28 января 2011
Public Property MyFoo As New Foo(Name)

Синтаксис «как новый» вызывает проблему. Отсроченная инициализация здесь не работает, компилятор генерирует код в конструкторе для инициализации свойства MyFoo. Этот внедренный код всегда выполняется перед любым кодом, который вы пишете сами.

Нет чистого исправления, вам придется использовать личное поле поддержки:

Public Class Dings
    Public Property Name As String
    Private fooBacking As Foo

    Public Property MyFoo As Foo
        Get
            Return fooBacking
        End Get
        Set(ByVal value As Foo)
            fooBacking = value
        End Set
    End Property

    Public Sub New(ByVal aName As String)
        _Name = aName
        MyFoo = New Foo(_Name)
    End Sub
End Class
2 голосов
/ 28 января 2011

Вы должны инициализировать ваше свойство MyFoo непосредственно из конструктора:

Public Class Form1
    Private d As New Dings("dings")
End Class
Public Class Foo
    Public Sub New(ByVal aName As String)
        MsgBox("new Foo """ & aName & """")
    End Sub
End Class
Public Class Dings
    Public Property Name As String
    Public Property MyFoo As Foo

    Public Sub New(ByVal aName As String)
        Name = aName
        MyFoo = New Foo(aName)
    End Sub
End Class

Это пока рекомендуемый способ (на мой взгляд), потому что вы сохраняете полный контроль над свойствами последовательности, которые инициализируются. На самом деле это хороший пример.

Но это зависит от типа объекта и от того, имеет ли он отношение к другим членам или условиям:

встроенная инициализация

  • объект является константой
  • объект является типом значения и не зависит от специального условия (например, отметка времени)
  • объект является ссылочным типом, но для инициализации используется конструктор по умолчанию

Конструктор

  • объект зависит от других членов этого класса
  • объект имеет особое условие (например, Date.Now)
  • имеет много членов: некоторые инициализируются внутри строки, а некоторые в конструкторе делают его менее читаемым, рассмотрим полную инициализацию в конструкторе
0 голосов
/ 28 января 2011

Чтобы ответить на часть C #, порядок инициализации в C #:

  • Все начинается со значения типа по умолчанию (ноль, 0 и т. Д.)
  • Присвоения, являющиеся частьюдекларации полей выполняются в текстовом порядке (т.е. в порядке их появления в исходном коде).Обратите внимание, что для частичных классов это приводит к некоторой неоднозначности.
  • Выполнен конструктор базового класса
  • Тело конструктора выполнено

Обратите внимание, что в C # вы не могливсе равно не пишите:

Public Property Name As String
Public Property MyFoo As New Foo(Name)
  • Автоматически реализованные свойства не могут иметь начальные значения как часть объявления
  • Нельзя использовать элементы экземпляра как часть объявленияпеременной экземпляра

Чтобы показать, что я подразумеваю под последней точкой, этот класс недопустим в C #:

class Test
{
    string x;
    string y = x;
}

, который генерирует эту ошибку во время компиляции:

Test.cs (6,16): ошибка CS0236: инициализатор поля не может ссылаться на нестатическое поле, метод или свойство 'Test.x'

...