1991년 Visual Basic 언어가 탄생한 이후 Visual Basic 언어는 응용 프로그램 구축을 위한 매우 효율적인 도구였습니다. 거의 20년이 지난 지금도 Microsoft .NET Framework와의 손쉬운 통합을 계속 제공하여 개발자가 데스크톱, 휴대폰, 브라우저는 물론 클라우드까지 포괄하는 애플리케이션을 작성할 수 있도록 합니다.
Microsoft는 이번 달 Visual Basic 버전 10(VB 2010 또는 VB10이라고도 함)이 포함된 Visual Studio 2010을 출시할 예정입니다. 이번 릴리스는 가장 강력하며 개발자가 더 적은 코드 줄로 더 많은 작업을 수행할 수 있도록 도와주는 많은 시간 절약 기능을 포함하고 있습니다. 여기에서는 Visual Studio 2010의 Visual Basic을 완전히 이해하고 활용하는 데 필요한 모든 콘텐츠가 제공됩니다.
공진화
과거에는 Visual Basic과 C#이 별도의 팀에서 개발되었기 때문에 기능이 한 언어에 먼저 나타나고 다른 언어에 나타나는 경우가 많았습니다. 예를 들어 C#에는 Visual Basic에서 사용할 수 없는 자동 구현 속성 및 컬렉션 이니셜라이저가 있고 Visual Basic에는 C#에서 사용할 수 없는 런타임 바인딩 및 선택적 매개 변수와 같은 기능이 있습니다. 그러나 언어에 새로운 기능이 추가될 때마다 많은 고객은 해당 기능을 다른 언어에도 추가해 달라고 요청합니다.
이러한 요구를 해결하기 위해 Microsoft는 Visual Basic과 C# 팀을 통합하여 공동 발전 전략을 구현했습니다. 목적은 이러한 언어의 공통 개발을 촉진하는 것입니다. 주요 기능이 한 언어에 도입되면 다른 언어에도 나타납니다. 그렇다고 모든 기능이 두 언어 모두에 존재하고 정확히 동일한 방식으로 작동한다는 것은 아닙니다. 실제로 각 언어에는 고유한 역사, 영혼 및 느낌이 있으며 이러한 특성을 보존하는 것이 중요합니다.
.NET Framework 4에서 Visual Basic과 C#은 서로의 기존 기능 중 많은 부분을 흡수하면서 이 목표를 향해 큰 진전을 이루었습니다. 그러나 공동 진화는 이전 기능에만 영향을 미치는 것이 아니라 이러한 언어의 향후 개발을 위한 전략이기도 합니다. 이러한 정신으로 .NET Framework 4는 동적 언어 런타임, 포함된 interop 유형, 일반 변형 등 두 언어 모두에 강력한 새 기능을 도입하여 Visual Basic 및 C# 개발자가 .NET Framework를 최대한 활용할 수 있도록 합니다.
비주얼 베이직 2010의 새로운 기능
Visual Basic 2010의 새로운 기능은 더 적은 코드 줄로 더 많은 작업을 수행할 수 있도록 설계되었습니다. 우리의 Visual Basic 디자인 팀은 개발자가 일반적으로 지루한 상용구 코드를 많이 작성해야 하는 부분을 면밀히 조사하고 대신 컴파일러가 작업을 수행하도록 하는 방법을 찾았습니다. 물론 이는 전체적인 관점이므로, 이제 각 기능을 좀 더 자세히 살펴보겠습니다.
암시적 줄 연속 문자
Visual Basic은 가독성을 높이기 위해 영어와 유사한 명확한 구문을 사용하는 줄 중심 언어입니다. 그러나 이로 인해 코드가 줄당 80자 제한에 도달하게 되어 개발자가 많은 스크롤을 수행해야 하는 경우가 많습니다. 밑줄 문자를 사용하여 다음 줄의 처리가 현재 줄로 계속되어야 함을 컴파일러에 알릴 수 있습니다(즉, 여러 물리적 줄을 단일 논리적 줄로 처리함). 그러나 밑줄 문자를 반복적으로 입력해야 하는 것은 짜증나는 일이었으며 실제로 수년 동안 가장 많이 요청된 기능은 컴파일러에서 이 문제를 해결하도록 하는 것이었습니다.
Visual Basic 2010에서는 컴파일러가 이 문제를 해결할 수 있습니다. 이제 컴파일러는 줄 연속 문자 앞에 나타나는 경향이 있는 토큰(예: 쉼표, 괄호 및 연산자)을 알고 있으며 개발자가 더 이상 문자를 삽입할 필요가 없도록 문자를 삽입합니다. 예를 들어 Visual Basic 문을 쉼표로 끝내는 것은 확실히 논리적이지 않습니다. 컴파일러는 이를 알고 있으므로 컴파일러는 {comma, enter}와 같은 토큰 스트림을 볼 때 줄 연속 문자가 있음을 추론합니다. 그림과 같이 1의 예가 표시됩니다.
그림 1 줄 연속 문자 추론
<Extension()>
함수 FilterByCountry(
ByVal 고객은 IEnumerable(고객)으로,
ByVal 국가 문자열) IEnumerable(고객)
희미한 쿼리=
C In 고객으로부터
여기서 c.국가 = 국가
<고객>을 선택하세요.
<%=
c.이름 &
, &
c.국가
%>
</고객>
쿼리 반환
기능 종료
Visual Basic 2008에서 그림 1의 코드에는 9개의 밑줄 문자가 필요합니다. 그러나 다음 각 경우에 컴파일러는 밑줄 문자가 필요한 시기를 추론하고 이를 무시하도록 허용합니다.
<Extension()> 속성 뒤
메소드 선언 후 ((왼쪽 괄호)
첫 번째 매개변수의 ,(쉼표) 뒤에
메소드 선언 전)(오른쪽 괄호)
=(등호) 이후
<%= 뒤(포함된 표현식의 여는 태그)
XML 텍스트의 각 앰퍼샌드(앰퍼샌드) 뒤
%> 앞(포함된 표현식의 끝 태그)
이 새로운 컴파일러 기능은 메소드 시그니처에 특히 유용합니다. 이는 표시된 예에서 80자보다 긴 경우에도 잘 작동합니다(각 부분이 같은 줄에 있는 경우). 그림 2에서는 줄 연속 문자가 암시적으로 포함된 태그와 위치의 모든 조합을 볼 수 있습니다.
그림 2 줄 연속 문자가 암시적인 경우
표시 | 전에 | ~ 후에 |
,(쉼표), .(마침표), >(속성), ( {(왼쪽 대괄호), <%=(내장 표현식 시작 태그(XML 텍스트)) | 엑스 | |
), }, ](오른쪽 대괄호), %>(내장 표현식 종료 태그) | 엑스 | |
모든 LINQ 키워드: 집계, 고유, 시작, 그룹화, 그룹 가입, 결합, 허용, 정렬 기준, 선택, 건너뛰기, 동안 건너뛰기, 가져오기, 가져오기 동안, 위치, 안으로, 안으로, 켜기, 오름차순, 내림차순 | 엑스 | 엑스 |
연산자: +, -,*,/,/,^,>>,<<,Mod,&,+=,-=,*=,/=,/=,^=,>>=,<<=, & =, <, <=, >, >=, <>, Is, IsNot, Like, And, Or, Xor, AndAlso, OrElse | 엑스 | |
With(객체 이니셜라이저에서) | 엑스 |
보시다시피 언어에는 밑줄 문자가 필요하지 않은 곳이 60개가 넘습니다. (실제로 이 문서의 코드 예제에는 줄 연속 문자가 필요하지 않습니다.) 물론 밑줄 문자를 계속 사용할 수 있으므로 이전 버전의 Visual Basic의 코드도 예상대로 컴파일됩니다.
명령문Lambda
람다라는 용어는 처음에는 무섭게 들릴 수 있지만 람다는 다른 함수 내에 정의된 함수일 뿐입니다. Visual Basic 2008에는 Function 키워드가 포함된 람다 식이 도입되었습니다.
Dim customers As Customer() = ...
Array.FindAll(고객, 함수(c) c.국가 = 캐나다)
람다 표현식을 사용하면 논리를 여러 메서드로 분할하지 않고도 세분화되고 간결한 방식으로 로컬에서 논리를 표현할 수 있습니다. 예를 들어 다음은 Visual Basic 2005(람다 식을 지원하지 않음)의 이전 코드 표현입니다.
Dim query = Array.FindAll(customers, AddressOf Filter)
...
기능 필터(ByVal c As customer) As Boolean
c.국가 = 캐나다 반환
기능 종료
안타깝게도 Visual Basic 2008의 람다 식에서는 값을 반환하는 식이 필요하므로 다음 코드는 다음과 같습니다.
Array.ForEach(customers, Function(c) Console.WriteLine(c.Country))
다음과 같은 상황이 발생합니다.
'Compile error: Expression does not produce a value.
Console.WriteLine은 Sub 프로시저(C#에서는 void)이므로 값을 반환하지 않으므로 컴파일러에서 오류가 생성됩니다. 이러한 상황을 처리하기 위해 Visual Basic 2010에서는 하나 이상의 문을 포함하는 람다인 문 람다에 대한 지원을 도입했습니다.
Array.ForEach(customers, Sub(c) Console.WriteLine(c.Country))
Console.WriteLine은 값을 반환하지 않으므로 Function 람다 대신 Sub 람다를 만들면 됩니다. 다음은 여러 문을 사용하는 또 다른 예입니다.
Array.ForEach(customers, Sub(c)
Console.WriteLine(국가명:)
Console.WriteLine(c.국가)
끝 하위)
이 코드가 실행되면 각 고객에 대해 두 줄이 인쇄됩니다. 또한 코딩하는 동안 c 위로 마우스를 가져가면 컴파일러가 유형을 Customer로 추론하는 것을 볼 수 있습니다(유형을 명시적으로 선언하기 위해 c As Customer를 입력하는 것도 적법합니다). 이벤트 핸들러를 동적으로 작성하는 것은 명령문 람다를 활용하는 또 다른 유용한 방법입니다.
AddHandler b.Click, Sub(sender As Object, e As EventArgs)
MsgBox(버튼을 눌렀을 때)
'여기에 더 복잡한 논리를 삽입하세요
서브 끝
그리고 실제로 Visual Basic 2008에 도입된 기능인 느슨한 위임과 함께 문 람다를 사용할 수 있습니다. (대리자(유형 안전 함수 포인터)를 사용하여 여러 함수를 동시에 실행할 수 있습니다.) 이 조합을 사용하면 서명이 훨씬 간단해집니다.
AddHandler b.Click, Sub()
MsgBox(버튼을 눌렀을 때)
'여기에 더 복잡한 논리를 삽입하세요
서브 끝
대리자 느슨함을 사용하면 이벤트 핸들러의 매개변수를 완전히 무시할 수 있습니다. 매개변수가 전혀 사용되지 않아 시각적으로만 방해가 되는 한 이는 좋은 이점입니다.
지금까지 본 단일 줄 Sub 람다와 여러 줄 Sub 람다 외에도 Visual Basic 2010에서는 여러 줄 함수 람다도 지원합니다.
Dim query = customers.Where(Function(c)
'저장되지 않은 고객만 반환
'여기에 더 복잡한 논리를 삽입하세요
c.ID = -1을 반환합니다.
기능 종료)
문 람다의 또 다른 흥미로운 측면은 Visual Basic 2008에 도입된 익명 대리자와 교차하는 방식입니다. 사람들은 엄격히 동일하지는 않지만 이러한 대리자를 C#의 익명 메서드와 혼동하는 경우가 많습니다. 익명 위임은 Visual Basic 컴파일러가 람다의 메서드 시그니처를 기반으로 대리자 형식을 유추할 때 발생합니다.
Dim method = Function(product As String)
제품 = 종이인 경우
재고가 있는 4.5' 단위 반품
또 다른
다른 모든 것의 10 '10을 반환합니다.
종료 조건
기능 종료
MsgBox(메서드(종이))
이 코드를 실행하면 메시지 상자에 값 4.5가 표시됩니다. 또한 메서드 위로 마우스를 가져가면 Dim method As <Function(String) As Double> 텍스트가 표시됩니다. 실제 대리자 유형을 제공하지 않았으므로 컴파일러는 다음과 같이 자동으로 대리자 유형을 생성합니다.
Delegate Function $compilerGeneratedName$(product As String) As Double
이는 작성된 코드가 아닌 컴파일러에 의해 생성된 코드에만 나타나기 때문에 익명 대리자라고 합니다. 실제로 람다의 반환 유형을 지정하기 위해 As 절이 제공되지 않으면 컴파일러는 반환 유형을 Double로 유추합니다. 컴파일러는 람다 내의 모든 반환 문을 살펴보고 Double(4.5) 및 Integer(10) 형식을 결정합니다.
'Notice the As Single
Dim 방법 = Function(product As String) As Single
제품 = 종이인 경우
재고가 있는 4.5' 단위 반품
또 다른
다른 모든 것의 10 '10을 반환합니다.
종료 조건
기능 종료
그런 다음 기본 유형 알고리즘을 실행하고 10을 Double로 안전하게 변환할 수 있지만 4.5를 Integer로 안전하게 변환할 수 없다고 판단합니다. 따라서 Double이 더 나은 선택입니다.
반환 유형을 명시적으로 제어할 수도 있습니다. 이 경우 컴파일러는 유형을 유추하지 않습니다. 대리자 형식을 유추하기 위해 컴파일러에 의존하는 대신 명시적인 대리자 형식을 사용하여 변수에 람다를 할당하는 것이 매우 일반적입니다.
Dim method As Func(Of String, Single) =
기능(제품)
제품 = 종이인 경우
재고가 있는 4.5' 단위 반품
또 다른
다른 모든 것의 10 '10을 반환합니다.
종료 조건
기능 종료
명시적인 대상 유형이 제공되므로 As String 또는 As Single을 선언할 필요가 없습니다. 컴파일러는 문의 왼쪽에 있는 대리자 유형을 기반으로 해당 유형의 존재를 추론할 수 있습니다. 따라서 제품 위로 마우스를 가져가면 유추된 유형이 문자열임을 알 수 있습니다. 대리자 유형이 이미 해당 정보를 제공하므로 더 이상 As Single을 지정할 필요가 없습니다. 이전 예제에서 Func 대리자(.NET Framework에 포함됨)의 서명은 다음과 같습니다.
Delegate Function Func(Of T, R)(ByVal param As T) As R
나중에 일반 분산 섹션에서 살펴보겠지만 작은 예외가 하나 있습니다.
자동 구현 속성
Visual Basic에서 속성은 개체의 상태를 외부에 노출하는 클래스 멤버입니다. 일반적인 속성 선언은 다음과 같습니다.
Private _Country As String
문자열로 된 속성 국가
얻다
반품_국가
종료 종료
Set(ByVal 값을 문자열로)
_국가 = 값
최종 세트
끝 속성
10줄의 코드로 구성된 매우 간단한 개념입니다. 일반적인 객체에는 수십 개의 속성이 있는 경우가 많기 때문에 클래스 정의에 많은 상용구 코드를 포함하게 됩니다. 이러한 작업을 단순화하기 위해 Visual Basic 2010에는 단 한 줄의 코드로 간단한 속성을 정의할 수 있는 자동 구현 속성이 도입되었습니다.
Property Country As String
이 경우 컴파일러는 계속 실행되어 getter, setter 및 지원 필드를 자동으로 생성합니다. 지원되는 필드의 이름은 항상 밑줄 문자가 앞에 오는 속성 이름입니다(이 예에서는 _Country). 이 명명 규칙은 자동 구현 속성을 일반 속성으로 변경할 때 이진 직렬화 호환성을 보장합니다. 지원 필드의 이름이 동일한 한 바이너리 직렬화는 계속 작동합니다.
자동으로 구현된 속성을 사용하여 수행할 수 있는 좋은 작업 중 하나는 생성자가 실행될 때 속성의 기본값을 설정하는 초기화 프로그램을 지정하는 것입니다. 예를 들어 엔터티 클래스가 포함된 일반적인 시나리오에서는 기본 키를 -1과 같은 값으로 설정하여 저장되지 않은 상태임을 나타냅니다. 코드는 다음과 같습니다:
Property ID As Integer = -1
생성자가 실행되면 지원 필드(_ID)가 자동으로 -1 값으로 설정됩니다. 초기화 구문은 참조 유형에도 작동합니다.
Property OrderList As List(Of Order) = New List(Of Order)
형식 이름을 두 번 입력할 필요가 없기 때문에 이전 코드 줄에는 Visual Basic 특성이 명확하지 않을 수 있습니다. 좋은 소식은 Visual Basic에서 허용하는 구문과 일치하는 일반 변수 선언에 대한 더 짧은 구문이 있다는 것입니다.
Property OrderList As New List(Of Order)
개체 이니셜라이저와 함께 이 구문을 사용하여 다른 속성을 설정할 수도 있습니다.
Property OrderList As New List(Of Order) With {.Capacity = 100}
분명히 더 복잡한 속성의 경우 확장된 구문이 여전히 필요합니다. 여전히 Property{Tab}을 입력하여 이전 속성 조각을 활성화할 수 있습니다. 또는 속성의 첫 번째 줄을 입력한 후 Get{Enter}만 입력하면 IDE가 이전 스타일 속성을 생성합니다.
Property Name As String
얻다
종료 종료
Set(ByVal 값을 문자열로)
최종 세트
끝 속성
일반적으로 새로운 속성 구문은 공개 필드의 구문과 거의 동일하므로 대신 공개 필드를 사용하지 않는 이유는 무엇입니까? 몇 가지 이유가 있습니다:
대부분의 .NET 데이터 바인딩 인프라는 필드가 아닌 속성 측면에서 작동합니다.
인터페이스는 필드의 존재를 강제할 수 없으며 속성의 존재를 강제할 수 있습니다.
속성은 비즈니스 규칙 변경에 대한 장기적인 유연성을 제공합니다. 예를 들어, 누군가 전화번호 길이가 10자리여야 한다는 규칙을 도입했다고 가정해 보겠습니다. 공개 필드에 할당된 경우 이 유효성 검사를 수행할 수 없습니다. 공용 필드를 속성으로 변경하는 것은 이진 직렬화 및 리플렉션과 같은 시나리오에 대한 주요 변경 사항입니다.
컬렉션 초기화
일반적인 .NET 방식은 컬렉션을 인스턴스화한 다음 각 요소에 대해 Add 메서드를 한 번씩 호출하여 컬렉션을 채우는 것입니다.
Dim digits As New List(Of Integer)
숫자.추가(0)
숫자.추가(1)
숫자.추가(2)
숫자.추가(3)
숫자.추가(4)
숫자.추가(5)
숫자.추가(6)
숫자.추가(7)
숫자.추가(8)
숫자.추가(9)
그러나 근본적으로 단순한 개념의 경우 구문상의 오버헤드가 많이 발생합니다. Visual Basic 2010에는 컬렉션을 더 쉽게 인스턴스화할 수 있도록 컬렉션 이니셜라이저가 도입되었습니다. 이 코드의 경우:
Dim digits = New List(Of Integer) From {1, 2, 3, 4, 5, 6, 7, 8, 9, 0}
컴파일러는 Add 메서드에 대한 모든 호출을 자동으로 생성합니다. Visual Basic의 As New 구문 기능을 사용할 수도 있습니다.
Dim digits As New List(Of Integer) From {1, 2, 3, 4, 5, 6, 7, 8, 9, 0}
Visual Basic 팀에서는 Option Infer 설정의 변경 사항에 대한 코드 탄력성을 높이기 때문에 항상 전자보다 두 번째 구문(새로)을 사용하는 것이 좋습니다.
다음 요구 사항을 충족하는 모든 형식에 대해 컬렉션 이니셜라이저를 사용할 수 있습니다.
For Each 문을 사용하여 유형을 반복할 수 있습니다. 즉, 유형이 IEnumerable을 구현합니다. (컬렉션 유형에 대한 더 정확하고 자세한 정의는 msdn.microsoft.com/library/aa711986(VS.71).aspx에서 Visual Basic 언어 사양의 섹션 10.9.3을 참조하세요.)
형식에는 매개 변수가 없는 액세스 가능한(반드시 공개는 아님) 생성자가 있습니다.
형식에는 Add라는 액세스 가능한(반드시 공용은 아님) 인스턴스 또는 확장 메서드가 있습니다.
이는 사전과 같은 더 복잡한 유형에 대해 컬렉션 이니셜라이저를 사용할 수도 있음을 의미합니다.
Dim lookupTable As New Dictionary(Of Integer, String) From
{{1, 하나},
{2, 2},
{3, 3},
{4, 4}}
(이 명령문은 5줄에 걸쳐 있지만 밑줄 문자가 없습니다.) 이 경우 컴파일러는 사전을 초기화하는 이전 방법과 동일한 코드를 생성합니다.
Dim lookupTable As New Dictionary(Of Integer, String)
조회테이블.추가(1, 하나)
조회테이블.추가(2, 2)
조회테이블.추가(3, 3)
조회테이블.추가(4, 4)
컴파일러는 하나가 아닌 두 개의 매개 변수를 사용하여 Add 메서드를 호출합니다. 컬렉션 이니셜라이저에 전달된 값이 {{1, One}, {2, Two}, …}와 같이 중첩된 중괄호 안에 있기 때문에 이 작업을 수행하는 것을 알고 있습니다. 각 중첩 중괄호 집합에 대해 컴파일러는 이러한 매개 변수를 호환 가능한 Add 메서드에 전달하려고 시도합니다.
확장 메소드를 사용하여 사용자 정의 Add 구현을 제공하는 것도 가능합니다.
<Extension()>
하위 추가(ByVal 소스를 IList(고객)로,
ByVal ID는 정수로,
ByVal 이름을 문자열로,
ByVal 도시를 문자열로)
source.Add(신규 고객
{
.ID = 아이디,
.이름 = 이름,
.도시 = 도시
})
서브 끝
(누락된 밑줄 문자를 모두 보십시오!) 이 메서드는 IList(Of Customer)를 구현하는 모든 유형을 확장한 다음 다음과 같이 새로운 컬렉션 이니셜라이저 구문을 사용할 수 있도록 합니다.
Dim list = New List(Of Customer) From
{
{1, 존, 레드먼드},
{2, 밥, 시애틀},
{3, 샐리, 토론토}
}
(목록에 고객 3명을 추가합니다.) 자동으로 구현된 속성과 함께 컬렉션 이니셜라이저를 사용할 수도 있습니다.
Property States As New List(Of String) From {AL, AK, AR, AZ, ...}
배열 리터럴
Visual Basic 2010은 컬렉션 형식을 사용하는 더욱 강력한 방법 외에도 배열 작업을 위한 몇 가지 강력한 향상된 기능도 제공합니다. 다음 코드를 가정합니다(이전 버전에서는 잘 작동함).
Dim numbers As Integer() = New Integer() {1, 2, 3, 4, 5}
이 배열의 요소를 보면 각 요소가 정수라는 것이 분명하므로 실제로 이 줄에서 정수를 두 번 인쇄해도 실제로는 값이 추가되지 않습니다. 배열 리터럴을 사용하면 배열의 모든 요소를 중괄호 안에 배치하고 컴파일러가 자동으로 유형을 추론하도록 하여 배열을 만들 수 있습니다.
Dim numbers = {1, 2, 3, 4, 5}
숫자 유형은 Object가 아니라 Integer()(Option Infer가 활성화된 경우)입니다. 그 이유는 배열 리터럴이 이제 자신을 나타내고 자체 유형을 갖기 때문입니다. 좀 더 복잡한 예를 가정해 보겠습니다.
Dim numbers = {1, 2, 3, 4, 5.555}
이 경우 숫자 유형은 Double()로 추론됩니다. 컴파일러는 문 람다의 반환 유형을 유추하기 위해 앞에서 설명한 것과 동일한 알고리즘을 사용하여 배열의 각 요소를 검사하고 기본 유형을 계산하여 유형을 결정합니다. 기본 유형이 없으면 어떻게 되나요? 예를 들어, 다음 코드에 표시된 대로:
Dim numbers = {1, 2, 3, 4, 5}
이 경우 Integer를 String으로 변환하면 변환 범위가 줄어들고(즉, 런타임 시 데이터 손실이 발생할 수 있음) 마찬가지로 String을 Integer로 변환하면 변환 범위도 줄어듭니다. 선택할 수 있는 유일한 안전한 유형은 Object()입니다(Option Strict가 활성화된 경우 컴파일러는 오류를 생성합니다).
배열 리터럴을 중첩하여 다차원 배열이나 들쭉날쭉한 배열을 형성할 수 있습니다.
'2-dimensional array
차원 행렬 = {{1, 0}, {0, 1}}
'가변 배열 - 괄호는 내부 배열을 먼저 평가하도록 합니다.
희미한 들쭉날쭉 = { ({1, 0}), ({0, 1}) }
동적 언어 런타임
Visual Basic은 기술적으로 본질적으로 정적 언어이지만 런타임 바인딩과 같은 매우 강력한 동적 기능을 항상 갖추고 있었습니다. Visual Studio 2010에는 동적 언어를 보다 쉽게 구축하고 언어 간 통신을 가능하게 하는 DLR(Dynamic Language Runtime)이라는 새로운 플랫폼이 포함되어 있습니다. Visual Basic 2010은 최신 바인더에서 DLR을 완벽하게 지원하도록 업데이트되어 개발자가 다른 언어(예: IronPython/IronRuby)로 개발된 라이브러리 및 프레임워크를 사용할 수 있습니다.
이 기능의 가장 큰 장점 중 하나는 구문상 아무것도 변경되지 않았다는 것입니다(사실 이 기능을 지원하기 위해 컴파일러에서 코드 한 줄도 수정되지 않았습니다). 개발자는 이전 버전의 Visual Basic에서와 마찬가지로 런타임에 바인딩 작업을 계속 수행할 수 있습니다. 변경된 것은 이제 DLR에서 제공하는 IDynamicMetaObjectProvider 인터페이스를 인식하는 Visual Basic 런타임(Microsoft.VisualBasic.dll)의 코드입니다. 개체가 이 인터페이스를 구현하는 경우 Visual Basic 런타임은 DLR CallSite를 구축하고 개체와 이를 제공하는 언어가 자체 의미 체계를 작업에 주입할 수 있도록 합니다.
예를 들어, Python 표준 라이브러리에는 배열의 요소를 무작위로 재배열하는 데 사용할 수 있는 shuffle이라는 메서드가 있는 random.py라는 파일이 포함되어 있습니다. 이 메서드를 호출하는 방법은 간단합니다.
Dim python As ScriptRuntime = Python.CreateRuntime()
희미한 무작위 개체 = python.UseFile(random.py)
희미한 항목 = {1, 2, 3, 4, 5, 6, 7}
무작위.셔플(항목)
런타임 시 Visual Basic은 개체가 IDynamicMetaObjectProvider를 구현하고 이에 따라 DLR에 제어권을 전달하는 것을 확인합니다. 그런 다음 DLR은 Python과 통신하고 메서드를 실행합니다(Visual Basic에 정의된 배열을 메서드에 매개 변수로 전달).
이는 DLR 지원 API를 호출하는 예이지만 개발자는 이 기능을 사용하는 자체 API를 만들 수도 있습니다. 핵심은 IDynamicMetaObjectProvider 인터페이스를 구현하는 것입니다. 이 경우 Visual Basic 및 C# 컴파일러는 특별한 동적 의미 체계를 사용하여 개체를 인식합니다. 이 인터페이스를 수동으로 구현하지 마십시오. System.Dynamic.DynamicObject 클래스(이미 이 인터페이스를 구현함)에서 상속하고 몇 가지 메서드만 재정의하는 것이 더 쉽습니다. 그림 3은 사용자 지정 동적 개체(즉석에서 속성을 만드는 것처럼 보이는 속성 모음)를 만들고 일반적인 Visual Basic 런타임 바인딩을 사용하여 개체를 호출하는 전체 예를 보여줍니다. (DynamicObject 사용에 대한 자세한 내용은 blogs.msdn.com/vbteam/archive/2010/01/20/fun-with-dynamic-objects-doug-rothaus.aspx에서 Doug Rothaus의 훌륭한 기사를 읽어보십시오.)
그림 3 사용자 지정 동적 개체 만들기 및 Visual Basic 런타임 바인딩을 사용하여 개체 호출
Imports System.Dynamic
모듈 모듈1
서브메인()
Dim p As Object = 새 PropertyBag
p.하나 = 1
p.2 = 2
p.3 = 3
Console.WriteLine(p.One)
Console.WriteLine(p.2)
Console.WriteLine(p.Three)
서브 끝
클래스 PropertyBag: DynamicObject를 상속합니다.
개인 값을 새 사전으로(문자열, 정수)
공개 재정의 함수 TrySetMember(
ByVal 바인더 SetMemberBinder로,
ByVal 값을 개체로) 부울로
값(바인더.이름) = 값
참을 반환
기능 종료
공개 재정의 함수 TryGetMember(
ByVal 바인더 GetMemberBinder로,
ByRef 결과를 객체로) 부울로
값을 반환합니다.TryGetValue(바인더.이름, 결과)
기능 종료
수업 종료
최종 모듈
일반적인 분산
이것은 처음에는 실제로 복잡해 보일 수 있는 함수(공분산 및 반공분산과 같은 용어 포함)이지만 실제로는 매우 간단합니다. IEnumerable(Of Apple) 유형의 개체가 있고 이를 IEnumerable(Of Fruit)에 할당하려는 경우 모든 Apple이 Fruit(상속을 통해 적용됨)이므로 이는 적법해야 합니다. 불행하게도 Visual Basic 2010 이전에는 CLR(공용 언어 런타임)에서 실제로 지원되었음에도 불구하고 컴파일러에서는 일반 변형이 지원되지 않았습니다.
그림 4의 예를 살펴보겠습니다. Visual Basic 2008에서 그림 4의 코드는 DimenabledOnly 줄(또는 Option Strict가 비활성화된 경우 런타임 예외)에서 컴파일 오류를 생성합니다. 해결 방법은 다음과 같이 .Cast 확장 메서드를 호출하는 것입니다.
'Old way, the call to Cast(Of Control) is no longer necessary in VB 2010
Dim 활성화Only = FilterEnabledOnly(buttons.Cast(Of Control))
Visual Basic 2010에서는 IEnumerable 인터페이스가 Out 한정자를 사용하여 공변으로 표시되었기 때문에 더 이상 필요하지 않습니다.
Interface IEnumerable(Of Out T)
...
종료 인터페이스
그림 4 일반 분산의 예
Option Strict On
공개 수업 양식1
Sub Form1_Load()는 MyBase.Load를 처리합니다.
버튼을 새 목록(버튼)으로 흐리게 표시
{
새로운 버튼
{
.이름 = btn알겠습니다,
.활성화 = 참
},
새로운 버튼
{
.이름 = btnCancel,
.활성화됨 = 거짓
}
}
DimenabledOnly = FilterEnabledOnly(버튼)
서브 끝
함수 FilterEnabledOnly(
ByVal 컨트롤은 IEnumerable(Of Control)로 제어됩니다.
) IEnumerable(제어)로
c In 컨트롤에서 복귀
c.Enabled = True인 경우
기능 종료
수업 종료
이는 일반 매개변수 T가 이제 변수(즉, 상속에 적합함)이며 컴파일러는 유형이 인터페이스에서 오는 경우에만 매개변수가 사용되도록 보장한다는 것을 의미합니다. 일반 매개변수는 역변수일 수도 있습니다. 즉, 입력된 위치에만 사용됩니다. 유형은 실제로 두 가지를 모두 가질 수 있습니다. 예를 들어 앞서 설명한 Func 대리자에는 반공변 매개 변수(전달된 내용에 대한)와 공변 매개 변수(반환 유형에 대한)가 모두 있습니다.
Delegate Function Func(Of In T, Out R)(ByVal param As T) As R
사용자 정의 인터페이스 및 대리자에서 In 및 Out 수정자를 사용할 수 있습니다. .NET Framework 4의 많은 공통 인터페이스와 대리자는 변수로 표시됩니다. 일반적인 예로는 모든 Action/Func 대리자, IEnumerable(Of T), IComparer(Of T), IQueryable(Of T) 등이 있습니다.
일반적인 변형의 가장 큰 장점은 전혀 걱정할 필요가 없는 기능이라는 것입니다. 제 역할을 하고 있다면 결코 눈치 채지 못할 것입니다. 한때 컴파일러 오류가 발생했거나 .Cast(Of T) 호출이 필요한 상황이 Visual Basic 2010에서는 제대로 작동합니다.
향상된 선택적 매개변수
선택적 매개 변수는 개발자가 보다 유연한 메서드를 구축하고 많은 메서드 오버로드로 인해 클래스가 복잡해지는 것을 방지할 수 있는 유용한 효율성 기능을 제공합니다. 과거에는 선택적 매개변수가 null(또는 내부가 아닌 구조 유형일지라도)이 될 수 없다는 약간의 제한이 있었습니다. 이제 Visual Basic 2010에서는 모든 값 유형의 선택적 매개 변수를 정의할 수 있습니다.
Sub DisplayOrder(ByVal customer As Customer,
ByVal orderID는 정수로,
선택적 ByVal 단위 정수 = 0,
선택적 ByVal backgroundColor 색상 = 없음)
서브 끝
이 예에서 단위는 Nullable(Of Integer) 유형이고 backgroundColor는 내용이 아닌 구조 유형이지만 여전히 선택적 매개 변수로 사용됩니다. Visual Basic 2010에서는 일반 선택적 매개 변수에 대한 지원도 향상되었습니다.
임베디드 상호 운용성 유형
COM 상호 운용성을 수행하는 응용 프로그램의 일반적인 약점은 PIA(주 상호 운용성 어셈블리)를 사용해야 한다는 것입니다. PIA는 COM 구성 요소에서 RCW(런타임 호출 가능 래퍼) 역할을 하며 이를 식별하는 고유한 GUID를 갖는 .NET 어셈블리입니다. .NET 어셈블리는 PIA와 통신하며 PIA는 COM과 .NET 간에 데이터를 이동하는 데 필요한 마샬링을 수행합니다.
안타깝게도 PIA는 최종 사용자 컴퓨터에 배포해야 하는 추가 DLL이므로 배포가 복잡해질 수 있습니다. 또한 버전 관리 문제가 발생할 수도 있습니다. 예를 들어 응용 프로그램이 Excel 2003과 Excel 2007 모두에서 작동하도록 하려면 응용 프로그램과 함께 두 PIA를 모두 배포해야 합니다.
포함된 interop 유형 기능은 애플리케이션에 직접 포함되지만 꼭 필요한 PIA의 유형과 멤버만 포함되므로 최종 사용자의 컴퓨터에 PIA를 배포할 필요가 없습니다.
기존 개체에 대해 이 기능을 활성화하려면(새 참조의 경우 기본적으로 활성화되어 있음) 솔루션 탐색기에서 참조를 선택하고 속성 창에서 Interop 유형 포함 옵션을 변경합니다(그림 5 참조). 또는 ming 명령줄 컴파일러로 컴파일하는 경우 /r 및 /reference 대신 /l(또는 /link) 스위치를 사용합니다.
그림 5 솔루션 탐색기에서 포함된 interop 유형 활성화
이 기능을 활성화하면 애플리케이션은 더 이상 PIA에 의존하지 않습니다. 실제로 Reflector 또는 ildasm에서 어셈블리를 열면 실제로 PIA에 대한 참조가 전혀 없음을 알 수 있습니다.
여러 목표
Visual Basic 2010의 모든 기능 중 가장 좋은 점은 .NET Framework 2.0부터 .NET Framework 3.5까지 대상으로 하는 프로젝트에서도 해당 기능을 사용할 수 있다는 것입니다. 즉, 암시적 줄 연속 문자, 배열 리터럴, 컬렉션 이니셜라이저, 문 람다, 자동으로 구현된 속성 등과 같은 기능을 .NET Framework 4의 대상을 변경하지 않고도 기존 프로젝트에서 모두 사용할 수 있습니다.
예외는 .NET Framework 4에서만 사용할 수 있는 유형에 의존하는 포함된 interop 유형입니다. 따라서 .NET Framework 버전 2.0~3.5를 대상으로 하는 경우 이 기능을 사용할 수 없습니다. 또한 변수로 표시된 형식은 .NET Framework 4에 있는 것처럼만 표시되므로 이전 예제에서 버전 2.0~3.5를 대상으로 하는 경우에도 .Cast(Of T)를 호출해야 합니다. 그러나 이러한 이전 버전을 대상으로 하는 경우 In/Out 수정자를 사용하여 고유한 변수 유형을 만들 수 있습니다.
애플리케이션의 현재 대상 프레임워크를 변경하려면 내 프로젝트를 두 번 클릭하고 컴파일 탭을 클릭한 다음 고급 컴파일 옵션을 클릭하고 하단에 있는 콤보 상자에서 선택합니다.
실제로 ming 명령줄에서 컴파일할 때 이 기능을 활성화하는 ming 명령줄 스위치는 없습니다. 실제로 컴파일러는 System.Object(일반적으로 mscorlib)의 정의를 제공하는 어셈블리와 어셈블리의 대상 프레임워크를 살펴본 다음 출력 어셈블리에 해당 값을 표시합니다. (컴파일러는 Silverlight 어셈블리를 생성할 때 이와 동일한 메커니즘을 사용합니다.) IDE를 사용하면 이 모든 것이 투명하게 발생하므로 일반적으로 걱정할 것이 없습니다.
시도에 오신 것을 환영합니다
보시다시피 Visual Basic 2010에는 더 적은 줄의 코드를 작성하고 컴파일러에서 더 많은 작업을 수행하도록 하면서도 생산성을 높일 수 있는 강력한 기능이 많이 있습니다. 이 기사에서는 언어 기능에 대해서만 설명했지만 Visual Basic 2010 IDE에는 수많은 향상된 기능이 있습니다. 몇 가지 개선 사항은 다음과 같습니다.
다음으로 이동
따옴표 강조 표시
사용으로 인해 생성됨
향상된 IntelliSense(하위 문자열 일치, 카멜케이스 조회, 제안 패턴 – 개발 스타일을 먼저 테스트하는 데 유용함)
다중 모니터 지원
줌
Visual Basic 팀은 Visual Basic 개선을 위한 노력에 대한 여러분의 의견을 듣고 싶습니다. Microsoft Connect에 대한 의견과 질문을 보내주세요. 언어 및 IDE 기능에 대해 자세히 알아보려면 msdn.com/vbasic에서 기사, 예제 및 방법 비디오가 포함된 콘텐츠를 확인하세요. 물론, 가장 좋은 학습 방법은 제품을 자세히 알아보고 사용해 보는 것이므로 이제 설치하여 사용해 볼 차례입니다.