2015-05-07 3 views
2

Я не уверен, как правильно это сформулировать. У меня есть класс, называемый BoundedString, который в основном выглядит следующим образом:Можно ли связать конкретное значение с полем во время компиляции?

Public Class BoundedString 

    Public Property Value() As String 
    Public Property MinLength() As Integer 
    Public Property MaxLength() As Integer 

End Class 

В другом месте в моем коде, я хочу, чтобы иметь возможность сказать:

Public Class SomeClass 
    Public Property StringField() As BoundedString(Of 3, 5) 
End Class 

Где 3 и 5 представляют собой значения MINLENGTH и Максимальная длина.

Таким образом, я могу статически указать информацию о моей строке. Самое близкое, что я обнаружил к этому, похоже, это дженерики или атрибуты, но я не думаю, что дженерики позволяют вам указывать конкретные значения. Кто-нибудь знает о языковой функции для этого?

+1

Похоже, вы хотите получить атрибуты для этого ... –

ответ

0

Вот как я добился этого с помощью атрибутов. Код работает:

  1. Определение набора атрибутов, MinLengthAttribute и MaxLengthAttribute, которые могут быть использованы на полях или свойствах.
  2. Определение метода, GetPropertyAttribute, который извлекает атрибут из свойства объекта.
  3. Использование GetPropertyAttribute для извлечения минимальной и максимальной длины BoundedString при ее создании.

Это позволяет связать длины непосредственно рядом с свойством, что делает определение класса довольно легко читаемым. При использовании GetPropertyAttribute для получения значений длины Min/Max бит, хотя бы, признается.

<AttributeUsage(AttributeTargets.Field Or AttributeTargets.Property)> 
Public Class MinLengthAttribute : Inherits Attribute 
    Public Property MinLength As Integer 

    ''' <param name="minimumLength">The minimum length of this field/property.</param> 
    Public Sub New(ByVal minimumLength As Integer) 
     minimumLength = minimumLength 
    End Sub 
End Class 

<AttributeUsage(AttributeTargets.Field Or AttributeTargets.Property)> 
Public Class MaxLengthAttribute : Inherits Attribute 
    Public Property MaxLength As Integer 

    ''' <param name="maximumLength">The maximum length of this field/property.</param> 
    Public Sub New(ByVal maximumLength As Integer) 
     MaxLength = maximumLength 
    End Sub 
End Class 

''' <summary> 
''' Gets the attribute TAttribute of the property <paramref name="strPropertyName" /> on this class. 
''' </summary> 
''' <typeparam name="TAttribute">The type of the attribute to retrieve.</typeparam> 
''' <param name="oObj">An object that has a property named <paramref name="strPropertyName"/>.</param> 
''' <param name="strPropertyName">The property to get an attribute from.</param> 
''' <remarks> 
''' Requires that <paramref name="strPropertyName"/> has only one attribute 
''' of type TAttribute. Throws an exception if this is not the case. 
''' </remarks> 
<Extension> 
Public Function GetPropertyAttribute(Of TAttribute As Attribute)(oObj As Object, 
                   ByVal strPropertyName As String) As TAttribute 
    Dim piPropertyInfo As PropertyInfo = oObj.GetType().GetProperty(strPropertyName) 
    Dim aobjAttributes As Object() = piPropertyInfo.GetCustomAttributes(True) 

    Dim lstAttributes As List(Of TAttribute) = (From objAttribute As Attribute In aobjAttributes.OfType(Of TAttribute)() 
               Select CType(objAttribute, TAttribute)).ToList() 

    If lstAttributes.Count = 1 Then 
     Return lstAttributes(0) 
    Else 
     Throw New InvalidOperationException("Property " & strPropertyName & " has " & lstAttributes.Count & 
              " attributes of provided type. GetPropertyAttribute requires that" & strPropertyName & 
              " only has one property of the provided type.") 
    End If 

End Function 

Public Class SomeClass 
    <MinLength(0)> 
    <MaxLength(30)> 
    Public Property String1 As BoundedString 

    <MinLength(5)> 
    <MaxLength(10)> 
    Public Property String2 As BoundedString 

    <MinLength(0)> 
    <MaxLength(100)> 
    Public Property String3 As BoundedString 

    Public Sub New(ByVal string1 As String, 
        ByVal string2 As String, 
        ByVal string3 As String) 
     String1 = New BoundedString(string1, 
            GetPropertyAttribute(Of MinLengthAttribute)("String1").MinLength, 
            GetPropertyAttribute(Of MaxLengthAttribute)("String1").MaxLength) 
     String2 = New BoundedString(string1, 
            GetPropertyAttribute(Of MinLengthAttribute)("String2").MinLength, 
            GetPropertyAttribute(Of MaxLengthAttribute)("String2").MaxLength) 
     String3 = New BoundedString(string1, 
            GetPropertyAttribute(Of MinLengthAttribute)("String3").MinLength, 
            GetPropertyAttribute(Of MaxLengthAttribute)("String3").MaxLength) 
    End Sub 
End Class 
+0

Я собираюсь принять этот ответ. Ответ @ Muhammed будет работать, я думаю, но мои рассуждения таковы: С ответом Мухаммеда, я должен добавить значение. MinLength/MaxLength = 3/5 проверить на установщик каждого свойства в каждом классе, который у меня есть. Это будет работать, но будет утомительным и, возможно, подверженным ошибкам. С помощью этого решения код в основном просто извлекает значение атрибута и использует его для длины min/max. Все еще немного утомительно, но я думаю, что он менее подвержен ошибкам. –

3

Может быть, вы должны переопределить метод New():

Public Class BoundedString 

    Public Property Value As String 
    Public Property MinLength As Integer 
    Public Property MaxLength As Integer 

    Public Sub New(myMinLength As Integer, myMaxLength As Integer) 
     MinLength = myMinLength 
     MaxLength = myMaxLength 
    End Sub 

End Class 

Public Class SomeClass 

    Dim _StringField As BoundedString 
    Public Property StringField As BoundedString 
     Get 
      Return _StringField 
     End Get 
     Set(value As BoundedString) 
      If value.MinLength = 3 AndAlso value.MaxLength = 5 Then 
       _StringField = value 
      End If 
     End Set 
    End Property 

End Class 
+0

Я не уверен, что это именно то, что было задано. Я думаю, что намерение состоит в том, что значение свойства StringField может быть ** только ** быть объектом BoundedString с MinLength 3 и MaxLength из 5. Чтобы убедиться, что у вас может быть код в StringField, который создает исключение, если MinLength/Неверные свойства MaxLength. Но это будет проверка времени выполнения, а не проверка времени компиляции. – Blackwood

+0

Правильно, это близко - я подумывал об этом. Я думаю, что это позже позволит вам сделать это, хотя я пытаюсь избежать: SomeClass.StringField = New BoundedString (3, 6). Идет некоторое исследование по атрибутам и напишет ответ на этот вопрос, если он будет работать. –

+0

@Blackwood Извините .. это мое плохое, и я не уверен, понимаю ли я, что вы сказали, так или иначе .. вы предлагаете удалить этот ответ? – Muhammad

Смежные вопросы