Да, ваш код поврежден.Что бы это ни стоило, вы не можете сделать это и в .NET - синтаксис делает его довольно однозначным, будь то в C #:
private string _priority;
public string Priority
{
get { return _priority; }
private set { _priority = value; }
}
... или в VB:
Private _priority As String
Public Property Priority() As String
Get
Return _priority
End Get
Private Set(ByVal value As String)
_priority = value
End Set
End Property
Свойство может быть Long
или String
, оно не может быть и тем и другим.Get
/ Let
/ Set
методы доступа должны быть согласованными, также в VBA.
Вы можете обмануть , потеряв безопасность типов и раннее связывание,сделав вашу собственность Variant
... но это не совсем хороший способ начать работу с ООП; -)
Public Enum PriorityLevel
NoPriority = 0
HighPriority
MediumPriority
LowPriority
End Enum
Private Type InstanceState
Priority As PriorityLevel
'...
End Type
Private this As InstanceState
Public Property Get Priority() As Variant
Priority = PriorityName(this.Priority)
End Property
Public Property Let Priority(ByVal value As Variant)
this.Priority = value
End Property
Private Function PriorityName(ByVal value As PriorityLevel) As String
Select Case value
Case HighPriority
PriorityName = "High"
Case MediumPriority
PriorityName = "Medium"
Case LowPriority
PriorityName= "Low"
Case Else
PriorityName= "Undefined"
End Select
End Function
Хотя это работает идеально и выглядит довольно аккуратно на поверхности, потребляя этокласс, когда вы не написали, это определенно будет удивительно: если вы установите (Let
) a Long
, вы по праву ожидаете также Get
a Long
.Этот класс требует наличия свойства PriorityName
get-only:
Public Property Get Priority() As PriorityLevel
Priority = this.Priority
End Property
Public Property Let Priority(ByVal value As PriorityLevel)
this.Priority = value
End Property
Public Property Get PriorityName() As String
Select Case this.Priority
Case HighPriority
PriorityName = "High"
Case MediumPriority
PriorityName = "Medium"
Case LowPriority
PriorityName = "Low"
Case Else
PriorityName = "Undefined"
End Select
End Property
Теперь преимущества раннего связывания и безопасности типов (независимо от того, что вы используете в VBA), становятся очевидными: когдавы пишете код, который присваивает свойство Priority
объекта этого типа, IntelliSense для типа Enum
направляет написание выражения:
![available enum members appear in a dropdown list](https://i.stack.imgur.com/IE7n5.png)
Более того, Enum
- это , абстрагирующее базовое числовое значение, которое становится неактуальным: вместо волшебного жесткого кода 1
код теперь говорит: HighPriority
.Кроме того, аксессор Get
настолько прост, насколько это возможно, и это очень хорошо: аксессор Get
никогда не должен вызывать ошибок, поэтому, чем проще, тем лучше.
Мораль истории: не делайтевзломайте безопасность типов, если вы можете помочь ей, сделайте все возможное, чтобы ваш код был ранним - избегайте Object
и Variant
, насколько это возможно;приведите Object
к известному классу / интерфейсу везде, где вы можете.
Например, предпочтите:
Dim sheet As Worksheet
' Workbook.Worksheets(index) returns Object; casting it to Worksheet
Set sheet = ActiveWorkbook.Worksheets(1)
sheet.Range("A1").Value = 42
Кому:
' "Range("A1").Value" is entirely late-bound. Beware of typos!
ActiveWorkbook.Worksheets(1).Range("A1").Value = 42