당신은, 물론, 단지 다음과 같이 거대한 Select Case
블록 수 :
Public Sub CreateDoc(templateNum As Integer)
Select Case templateNum
Case 1
CreateDoc1()
Case 2
CreateDoc2()
Case 3
CreateDoc3()
End Select
End Sub
당신은 아마 더 나은, 더 간단한 방법이 될 것입니다 경우 문 상당히 적은 수 있던 경우에. 그러나 설명대로 많은 다양한 ID를 찾을 수 있다면 실용적이지 않으며 큰 Select Case
블록이 없으면 올바른 방법을 호출하고자하는 바램에 감사드립니다.
그러나 내가 들어가기 전에 다른 옵션을 주어야한다고 생각합니다. 아마 당신은 그 많은 다른 방법을 가질 필요가 없을 것입니다. 예를 들어, 템플리트 ID의 절반은 실제로 모두 동일한 방식으로 처리되어야하며, 유일한 차이점은 템플리트 파일 이름이 달라야한다는 것입니다. 그렇다면 Select Case
블록이 그만큼 클 필요가 없다고 생각할 수 있습니다. 예를 들면 다음과 같습니다.
Public Sub CreateDoc(templateNum As Integer)
Select Case templateNum
Case 1 To 100
CreateWriterDoc(GetTemplateFilePath(templateNum))
Case 101 To 200
CreateCalcDoc(GetTemplateFilePath(templateNum))
End Select
End Sub
Private Sub CreateWriterDoc(templateFilePath As String)
' Launch Writer with given template file
End Sub
Private Sub CreateCalcDoc(templateFilePath As String)
' Launch Calc with given template file
End Sub
Private Function GetTemplateFilePath(templateNum As Integer) As String
' Retrieve template file path for given ID
' (from DB, Array, List, Dictionary, etc.) and return it
End Sub
나에게 이것은 훨씬 간단한 해결책처럼 보입니다. 그렇지 않은 경우 - 실제로 각기 다른 템플릿 ID에 대해 실행해야하는 완전히 다른 논리가있는 경우 여러 가지 방법으로 수행 할 수 있습니다. 첫 번째 옵션은 각 ID를 호출 할 적절한 메서드를 가리키는 대리자 목록을 만드는 것입니다. 예를 들어, 다음과 같이 배열에 저장할 수 :
Dim createDocDelegates() As Action =
{
AddressOf CreateDoc1,
AddressOf CreateDoc2,
AddressOf CreateDoc3
}
그래서 지금, 그 세 대표가 배열에 (0 ~ 2) 번호에 의해 색인되어있다.이 같은 번호로 그들을 호출 할 수 있습니다 : 다음
Dim createDocDelegates As New Dictionary(Of Integer, Action)()
createDocDelegates.Add(1, AddressOf CreateDoc1)
createDocDelegates.Add(7, AddressOf CreateDoc7)
createDocDelegates.Add(20, AddressOf CreateDoc20)
을 수행 할 수 있습니다 : 당신의 ID 년대 순차적하지 않은 경우
가
createDocDelegates(1).Invoke() ' Calls CreateDoc2
또는,이 같이 대신, Dictionary(Of Integer, Action)
사용할 수 있습니다 이 같은 ID 하나를 호출
createDocDelegates(7).Invoke() ' Calls CreateDoc7
또 다른 옵션은 다음과 같이 문서를 생성하는 개체에 대한 Interface
을 생성하는 것입니다 :
Public Interface IDocCreator
Sub CreateDoc()
End Interface
그런 다음 각각의 동일한 인터페이스를 구현하는 각 유형의 템플릿에 대해 별도의 클래스를 구현할 수 있습니다. 예를 들어 :
Public Class Doc1Creator
Implements IDocCreator
Public Sub CreateDoc() Implements IDocCreator
' Do work
End Sub
End Class
Public Class Doc2Creator
Implements IDocCreator
Public Sub CreateDoc() Implements IDocCreator
' Do different work
End Sub
End Class
그런 다음 다음과 같이 해당 개체의 목록을 만들 수 있습니다
Dim docCreators() As IDocCreator =
{
New DocCreator1(),
New DocCreator2()
}
또는 :
Dim docCreators As New Dictionary(Of Integer, IDocCreator)()
docCreators.Add(1, New DocCreator1())
docCreators.Add(7, New DocCreator7())
docCreators.Add(20, New DocCreator7())
를 그리고이 같은 하나를 호출 할 수 있습니다
를
docCreators(1).CreateDoc()
IDocCreator
appr oach는 Delegate
접근 방식과 매우 유사합니다. 그것을하는 옳고 그른 방법도 아닙니다. 그것은 당신의 스타일, 당신이 편안하고 요구 사항에 따라 다릅니다. IDocCreator
접근 방식의 가장 큰 장점은 앞으로 더 많은 속성과 메서드를 쉽게 추가 할 수 있다는 것입니다. 예를 들어, 각 템플리트에 대해 사용자에게 친숙하고 설명이 담긴 이름을 어딘가에 저장하려고한다고 가정 해보십시오. IDocCreator
인터페이스에 ReadOnly Property Name As String
속성을 추가하는 것은 매우 쉽지만 위임자 목록 경로를 사용하면 더 어렵고 어색 할 것입니다.
그러나 위의 예에서 모든 방법이나 대리인 목록을 추가해야합니다. 따라서 거대한 Select Case
블록보다 약간 못 생겨도 여전히 충분하지 않을 수 있습니다. 그렇다면 당신이 사용해야하는 기술은 Reflection입니다. System.Reflection
네임 스페이스에는 많은 리플렉션 관련 기능이 포함되어 있습니다. 리플렉션을 사용하면 코드의 일부에 동적으로 액세스하고 호출 할 수 있습니다. 예를 들어, 리플렉션을 사용하여 주어진 클래스에 의해 정의 된 모든 특성 또는 메소드 목록을 얻을 수 있습니다. 또는 리플렉션을 사용하여 어셈블리에서 정의한 형식 목록을 가져올 수 있습니다. 리플렉션을 사용하면 문자열 이름을 기준으로 메서드를 가져온 다음 메서드를 호출 할 수 있습니다. 현재 개체의 "CreateDoc1"
메소드를 호출 할 경우에 따라서, 예를 들어, 당신은 이런 식으로 그것을 할 수 :
Me.GetType().GetMethod("CreateDoc1").Invoke(Me, {})
당신은 문자열의 이름을 호출하기 때문에, 당신은 연결을 통해 메소드 이름을 만들 수 : 대신 메소드의 이름을 사용하는 반사 방법을 사용하려는 경우
Dim methodName As String = "CreateDoc" & templateNum.ToString()
Me.GetType().GetMethod(methodName).Invoke(Me, {})
그러나, 그런 식으로, 그것은 청소기 될 것이다, 내 의견으로는, 각 방법에 태그를 사용자 지정 특성을 사용하는 .예를 들어, 당신이 이런 식으로 당신의 방법을 장식 할 수있는 속성 클래스 만들 수 있습니다 실행시
<CreateDocMethod(1)>
Public Sub CreateDoc1()
' ...
End Sub
다음을, 당신은 그 특정 속성과이 모든 방법을 찾기 위해 반사를 사용할 수 있습니다 오른쪽 하나를 호출합니다.
마지막으로 반영에 토론을 저장 한 이유는 효율적이지 않고 부서지기 쉬운 코드로 이어질 수 있기 때문입니다. 따라서 리플렉션을 최후의 수단으로 사용하는 것이 가장 좋습니다. 리플렉션에는 아무런 문제가 없습니다. 실제로 필요하다면,하지만 일반적으로, 리플렉션을 요구하지 않는 또 다른 합리적인 방법이 있다면, 아마도 다른 방식으로해야 할 것입니다.
템플릿의 ID는 항상 정수입니까? 일치하는 경우 ID 번호 순차에 간격이 있습니까? –
지금까지 시도한 내용의 샘플을 제공 할 수 있습니까? – StingyJack
예. ID는 정수이고 순차적입니다. – Dschon