2013-10-08 2 views
2

물리적 특성 측정 값을 사용하는 앱을 구축하고 있습니다. ,일반 유형이 인터페이스를 구현하고 해당 인터페이스를 사용하는지 테스트합니다.

Public Class ResultData 
    Public Property position_in_mm_vs_time_in_ms as Double(,) 
    Public Property initial_position_in_mm as Double 
    Public Property final_position_in_mm as Double 
    Public Property duration_in_ms as Double 
    Public Property speed_in_mm_per_s as Double 
End Class 

하지만 난 더 많은 항목 더 많은 속성을 추가로이 신속하게 엉망이되었다 : 처음에, I 형 '더블'의 변수의 전체 무리를 사용 헝가리 표기법 또는 내 머리에있는 값을 추적 유지 값이 미터 또는 밀리 암페어인지 여부를 알 수있는 방법이 없으며 하드 코딩 및 수동 추적이없는 항목의 적절한 약어가 무엇인지 알 수없고 입력 및 출력 옵션을 추가하는 아이디어 SI 또는 제국 단위의 데이터는 두려웠습니다.

나는이 문제가 타이핑 문제 것을 깨달았다, 나는이 배열을 개선하기 위해 유형과 값을 가진 클래스를 사용할 수 :

Namespace Measure 
    Public Class Value(Of GenericUnits) 
     Public Property Value As Double 
    End Class 
    Public Class ValuePoint(Of XUnits, YUnits) 
     Public X As Value(Of XUnits) 
     Public Y As Value(Of YUnits) 
     Public Sub New(x As Value(Of XUnits), y As Value(Of YUnits)) 
      Me.X = x 
      Me.Y = y 
     End Sub 
    End Class 
    Public Class Units 
     Public Interface GenericUnits 
      ReadOnly Property Abbreviation As String 
      ' Additional properties, operators, and conversion functions 
     End Interface 
     ' Additional unit types 
    End Class 
End Namespace 

나의 선언되었다 :

Public Class ResultData 
    Public Property PositionData as List(of ValuePoint(of Units.Seconds, Units.Millimeters)) 
    Public Property InitialPosition as Value(of Units.Millimeters) 
    Public Property FinalPosition as Value(of Units.Millimeters) 
    Public Property Duration as Value(of Units.Milliseconds) 
    Public Property Speed as Value(of Units.MillimetersPerSecond) 
End Class 

정말 멋지고 깨끗합니다. 지금 나는 내 운영자에 의해 정의 된 속성과 변환을 사용하려면,하지만 난 할 수 없습니다 :

Dim result As New ResultData() 
Dim msg As New System.Text.StringBuilder() 
msg.AppendLine("Speed units are abbreviated as: ") 
msg.AppendLine(result.Speed.GetType().ToString() & "?") 
msg.AppendLine(result.Speed.GetType().GenericTypeArguments(0).ToString() & "?") 
' Produces error "Abbreviation is not a member of System.Type" 
' Casting produces conversion error 
'msg.AppendLine(result.Speed.GetType().GenericTypeArguments(0).Abbreviation & "?") 
' Produces: 
' Speed units are abbreviated as: 
' Measure.Value`1[Measure.Units+MillimetersPerSecond] 
' Measure.Units+MillimetersPerSecond 
MsgBox(msg.ToString()) 
나는 내 타입이 선언의 속성과 메서드에 액세스 할 수있는 방법을

?

내 선언 Value(Of GenericUnits)은 실제로 GenericUnits이라는 인터페이스를 참조하지 않고 대신 generic 형식을 생성합니다. 나는 Value(Of T)라고 부를 수도있다. 나는 이것이 내 문제와 관련이있을 것이라고 생각한다.

답변

1

대부분 제네릭을 건너 뜁니다. 원하는 작업의 요점은 밀리미터 (milli), 밀리 암페어 (milliamp) 등 각 단위에 대한 유형 안전 컨테이너를 만드는 것입니다. 밀리 암페어를 예상하는 계산에서는 밀리미터를 사용하지 못하게하려고합니다. 일반적인 값인 컬렉션이있는 경우에도 이러한 실수는 계속 발생할 수 있습니다.

조치는 계량을위한 공통 인터페이스를 정의하는 것입니다.그러나 Value를 포함하는 것은 인터페이스의 일부 여야합니다. 나는 여전히 밀리 암페어와 밀리미터와 같은 것들을위한 특정 타입을 구현할 것입니다. 이러한 유형에는 암시 적 또는 명시 적 변환이 내장되어있을 수도 있습니다. 그러나 새로 작성하지 않고 .NET에 이미 포함되어있는 기존 제네릭 모음 및 유형을 사용합니다. 유형을 사용하는 경우 더 중요한 것은, 내가 마지막, 콘크리트 종류를 요청하고 인터페이스를 구현하고, 인터페이스 자체를 요구하지 않도록 것이다 : 나는 심지어 전체 추상 기본 클래스를 사용하는 유혹 될 수

Public Interface IUnit 
    ReadOnly Property Abbreviation As String 
    Property Value As Double 
End Interface 

Public Class MilliAmps Implements IUnit 
    Public ReadOnly Property Abbreviation As String Implements IUnit.Abbreviation 
     Get 
      Return "ma" 
     End Get 
    End Property 

    Public Property Value As Double Implements IUnit.Value 
End Class 

Public Class Millimeters Implements IUnit 
    Public ReadOnly Property Abbreviation As String Implements IUnit.Abbreviation 
     Get 
      Return "mm" 
     End Get 
    End Property 

    Public Property Value As Double Implements IUnit.Value 
End Class 
Public Class Seconds ... 
Public Class MillimetersPerSecond ... 

Public Class ResultData 
    Public Property PositionData As List(Of Tuple(Of Seconds, Millimeters)) 
    Public Property InitialPosition As Millimeters 
    Public Property FinalPosition As Millimeters 
    Public Property Duration As Milliseconds 
    Public Property Speed As MillimetersPerSecond 
End Class 

, 왜냐하면 같은 값의 프로퍼티를 계속해서 다시 구현하는 것을 피할 수 있었기 때문입니다.

+0

그건 합리적인 것 같습니다. 최종 코멘트에 관해서는 완전히 추상적 인 기본 클래스가 메소드를 다시 구현하도록 요구하지는 않습니까? 대신 우리는 완전한 기본 클래스를 원한다고 생각합니다. – kvermeer

+0

@kvermeer 클래스 추상 (VB : MustInherit)을 표시하면 인스턴스를 상속해야한다는 것을 의미하므로 인스턴스를 직접 만들 수는 없습니다. MustInherit 유형에서 구체적인 메소드를 가질 수 있습니다. –

+0

아, 그건 이해가 돼요! 감사. 지금 원활하게 일하고있는 것 같습니다 .... – kvermeer

2

당신은 당신의 인터페이스에서 파생 제네릭을 제한해야합니다

Public Class Measurement(Of T as IGenericUnits) 'class name was Value before edit 
    Public Property Value As Double 
    Public Property UOM As IGenericUnits 'UOM is a common abbreviation for unit-of-measure 
End Class 

제네릭 제약 조건에 대한 추가 정보를 원하시면 여기를 참조하십시오 : http://msdn.microsoft.com/en-us/library/w256ka79.aspx


편집 :

사용이 될 것이다

msg.AppendLine(result.Speed.UOM.Abbreviation) 

권고의 몇 :

  1. or MeasuredValue` 대신 Value" for your measurement class.is used all over the place and you are bound to run into a naming conflict eventually. Perhaps 측정보다 더 좋은 이름을 찾기 추천 명명 규칙

  2. 을 따라 IGenericUnitsGenericUnits 이름을 바꿉니다.

+0

감사합니다. 구문을 놓쳤습니다. 그러나 GetType은 여전히 ​​System.Type을 반환합니다. Value (또는 Measure 또는 MeasuredValue) 클래스에서 이것을 다시 구현하여 IGenericUnits를 반환해야합니까? – kvermeer

+0

System.RuntimeType을 내 IGenericUnits 유형으로 캐스팅하는 데 더 많은 문제가 발생한 후에 Joel의 대답과 함께 제네릭 전체를 건너 뛰기로 결정했지만 도움을 주셔서 감사합니다. – kvermeer

+0

후회를 위해 질문에 답변했습니다. – tcarvin

관련 문제