C # v4와 함께 제공되는 새 키워드에 대한 많은 기사를 읽었지만 "동적"과 "var"의 차이점을 알 수 없었습니다.
이 기사 는 그것에 대해 생각하게 만들었지 만 여전히 차이점을 볼 수는 없습니다.
"var"을 로컬 변수로만 사용할 수 있고 로컬 및 글로벌 모두로 동적으로 사용할 수 있습니까?
동적 키워드없이 일부 코드를 표시 한 다음 동적 키워드로 동일한 코드를 표시 할 수 있습니까?
C # v4와 함께 제공되는 새 키워드에 대한 많은 기사를 읽었지만 "동적"과 "var"의 차이점을 알 수 없었습니다.
이 기사 는 그것에 대해 생각하게 만들었지 만 여전히 차이점을 볼 수는 없습니다.
"var"을 로컬 변수로만 사용할 수 있고 로컬 및 글로벌 모두로 동적으로 사용할 수 있습니까?
동적 키워드없이 일부 코드를 표시 한 다음 동적 키워드로 동일한 코드를 표시 할 수 있습니까?
답변:
var
정적 유형입니다-컴파일러와 런타임 은 유형을 알고 있습니다 -입력을 저장하면됩니다 ... 다음은 100 % 동일합니다.
var s = "abc";
Console.WriteLine(s.Length);
과
string s = "abc";
Console.WriteLine(s.Length);
일어난 모두는 것이 었습니다 컴파일러는 것을 알아 냈 s
(이니셜)에서 문자열이어야합니다. 두 경우 모두 (IL) s.Length
에서 (인스턴스) string.Length
속성 을 의미합니다 .
dynamic
A는 매우 다른 짐승; 와 가장 유사 object
하지만 동적 디스패치가 있습니다.
dynamic s = "abc";
Console.WriteLine(s.Length);
여기에 dynamics
으로 입력 됩니다 . 그것에 대해 알지 못한다 string.Length
는 모르기 때문에, 아무것도 에 대한 s
컴파일 타임에 있습니다. 예를 들어 다음은 컴파일되지만 실행되지는 않습니다.
dynamic s = "abc";
Console.WriteLine(s.FlibbleBananaSnowball);
런타임 (전용), 그것은 것입니다 확인 에 대한 FlibbleBananaSnowball
재산 - 그것을 찾기 위해 실패, 그리고 불꽃의 샤워에서 폭발.
을 사용 dynamic
하면 속성 / 메소드 / 연산자 / 등이 실제 객체를 기반으로 런타임에 해결 됩니다 . COM (런타임 전용 속성을 가질 수 있음), DLR 또는와 같은 다른 동적 시스템과 대화 할 때 매우 편리합니다 javascript
.
var
하위 유형과 암시 적 캐스트로 인해 바람직하지 않은 유형을 유추 할 수 있다는 점에 유의해야합니다 . 즉, 묵시적 캐스트가 발생할 var
때 예상보다 정적으로 다른 유형을 해결했을 수 있습니다 (주로 더 일반적인 유형이지만 이에 국한되지 않음). 일반의 예는 대 대 하지만, 다른 더의 비열한 (사실적인)의 경우가 발생할 수 있습니다 미묘한 버그가 발생할 수 있습니다. object x = ""
var x = ""
var x = "" as object
WriteLine
어느 것인지 정확히 알고 있습니다. 이 "바인딩"은 컴파일 타임에 발생합니다. 의 경우에는 dynamic
,의 유형 .Length
이어야 dynamic
도, 그리고 그것은의 (전혀있는 경우) 과부하를 결정 런타임 때까지하지 WriteLine
맞는 최고. 바인딩은 런타임에 발생합니다.
var
Visual Studio 에서 키워드 를 가리키면 추론되는 실제 유형이 표시됩니다. 컴파일 타임에 해당 유형이 알려져 있음을 나타냅니다.
dynamic 과 var의 차이점을 설명하려고합니다 .
dynamic d1;
d1 = 1;
d1 = "http://mycodelogic.com";
작동합니다. 컴파일러는 동적 변수 유형을 다시 만들 수 있습니다 .
먼저 형식을 정수 로 만들고 그 후에 컴파일러는 형식을 문자열 로 다시
만들지 만 var의 경우
var v1; // Compiler will throw error because we have to initialized at the time of declaration
var v2 = 1; // Compiler will create v1 as **integer**
v2 = "Suneel Gupta"; // Compiler will throw error because, compiler will not recreate the type of variable
' var '키워드를 사용하는 경우 컴파일 타임에 컴파일러에서 유형이 결정되는 반면 ' dynamic '키워드를 사용하는 경우 런타임에 의해 유형이 결정됩니다.
' var '키워드는 컴파일러가 초기화 표현식에서 유형을 판별 할 수있는 암시 적으로 유형이 지정된 로컬 변수입니다. LINQ 프로그래밍을 수행 할 때 매우 유용합니다.
컴파일러에는 동적 유형의 변수 에 대한 정보가 없습니다 . 따라서 컴파일러는 지능을 보여주지 않습니다.
컴파일러에는 var 유형 의 저장된 값에 대한 모든 정보가 있으므로 컴파일러는 지능을 보여줍니다.
동적 유형은 함수 인수로 전달 될 수 있고 함수는 객체 유형을 리턴 할 수
있지만
var 유형은 함수 인수로 전달 될 수 없으며 함수는 오브젝트 유형을 리턴 할 수 없습니다. 이 유형의 변수는 정의 된 범위에서 작동 할 수 있습니다.
var는 정적 형식 검사 (초기 바인딩)가 적용되었음을 나타냅니다. dynamic은 동적 유형 검사 (후기 바인딩)가 적용됨을 의미합니다. 코드 측면에서 다음을 고려하십시오.
class Junk
{
public void Hello()
{
Console.WriteLine("Hello");
}
}
class Program
{
static void Main(String[] args)
{
var a = new Junk();
dynamic b = new Junk();
a.Hello();
b.Hello();
}
}
이것을 컴파일하고 ILSpy로 결과를 검사하면 컴파일러가 b에서 Hello ()에 대한 호출을 처리하는 늦은 바인딩 코드를 추가 한 반면 초기 바인딩이 a에 적용되었으므로 a는 Hello를 호출 할 수 있음을 알 수 있습니다 () 직접.
예 (ILSpy 분해)
using System;
namespace ConsoleApplication1
{
internal class Junk
{
public void Hello()
{
Console.WriteLine("Hello");
}
}
}
using Microsoft.CSharp.RuntimeBinder;
using System;
using System.Runtime.CompilerServices;
namespace ConsoleApplication1
{
internal class Program
{
[CompilerGenerated]
private static class <Main>o__SiteContainer0
{
public static CallSite<Action<CallSite, object>> <>p__Site1;
}
private static void Main(string[] args)
{
Junk a = new Junk(); //NOTE: Compiler converted var to Junk
object b = new Junk(); //NOTE: Compiler converted dynamic to object
a.Hello(); //Already Junk so just call the method.
//NOTE: Runtime binding (late binding) implementation added by compiler.
if (Program.<Main>o__SiteContainer0.<>p__Site1 == null)
{
Program.<Main>o__SiteContainer0.<>p__Site1 = CallSite<Action<CallSite, object>>.Create(Binder.InvokeMember(CSharpBinderFlags.ResultDiscarded, "Hello", null, typeof(Program), new CSharpArgumentInfo[]
{
CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null)
}));
}
Program.<Main>o__SiteContainer0.<>p__Site1.Target(Program.<Main>o__SiteContainer0.<>p__Site1, b);
}
}
}
차이점을 발견하기 위해 할 수있는 최선의 방법은 이와 같은 작은 콘솔 앱을 작성하고 ILSpy로 직접 테스트하는 것입니다.
한 가지 큰 차이점-동적 반환 유형을 가질 수 있습니다.
dynamic Foo(int x)
{
dynamic result;
if (x < 5)
result = x;
else
result = x.ToString();
return result;
}
다음은 Dynamic (4.0)과 Var의 차이점을 보여주는 간단한 예입니다.
dynamic di = 20;
dynamic ds = "sadlfk";
var vi = 10;
var vsTemp= "sdklf";
Console.WriteLine(di.GetType().ToString()); //Prints System.Int32
Console.WriteLine(ds.GetType().ToString()); //Prints System.String
Console.WriteLine(vi.GetType().ToString()); //Prints System.Int32
Console.WriteLine(vsTemp.GetType().ToString()); //Prints System.String
**ds = 12;** //ds is treated as string until this stmt now assigning integer.
Console.WriteLine(ds.GetType().ToString()); **//Prints System.Int32**
**vs = 12**; //*Gives compile time error* - Here is the difference between Var and Dynamic. var is compile time bound variable.
시바 마 미디
**
코드 예제에서 문자 가 존재한다는 것은 강조만을 나타 내기위한 것이며 실제 작업 코드의 일부가 아닙니다.
이것은 실제 데모를 통해 var
VS Dynamic
에 대해 이야기하는 멋진 YouTube 비디오입니다 .
아래는 스냅 샷에 대한 자세한 설명입니다.
동적은 늦은 바인딩 (동적으로 평가)되는 동안 Var은 초기에 바인딩 (정적으로 검사)됩니다.
Var 키워드는 오른쪽 데이터를 확인한 다음 컴파일 시간 동안 왼쪽 데이터 형식을 결정합니다. 즉, var 키워드는 입력 내용을 많이 저장합니다. 툴팁에서 문자열 데이터를 제공하고 x 변수가 문자열 데이터 유형을 표시 할 때 아래 이미지를 살펴보십시오.
반면에 동적 키워드는 완전히 다른 목적을위한 것입니다. 동적 객체는 런타임 중에 평가됩니다. 예를 들어 아래 코드에서 "Length"속성이 존재하는지 여부는 런타임 동안 평가됩니다. 의도적으로 작은 "l"을 입력 했으므로이 프로그램은 정상적으로 컴파일되었지만 실제로 실행될 때 "length"속성이있을 때 오류가 발생했습니다. (작은 "l")이라고합니다.
동적 변수 및 var 변수는 모든 유형의 값을 저장할 수 있지만 선언시 'var'을 초기화하는 데 필요합니다.
컴파일러에는 '동적'변수 유형에 대한 정보가 없습니다. var는 컴파일러에 안전합니다. 즉, 컴파일러에는 저장된 값에 대한 모든 정보가 있으므로 런타임시 아무런 문제가 발생하지 않습니다.
동적 유형은 함수 인수로 전달 될 수 있으며 함수도이를 리턴 할 수 있습니다. Var 형식은 함수 인수로 전달할 수 없으며 함수는 개체 형식을 반환 할 수 없습니다. 이 유형의 변수는 정의 된 범위에서 작동 할 수 있습니다.
동적 캐스팅의 경우에는 필요하지 않지만 stored type과 관련된 속성 및 메서드를 알아야합니다. var의 경우 컴파일러에서 작업을 수행하기위한 모든 정보가 있으므로 캐스팅 할 필요가 없습니다.
dynamic : 리플렉션 또는 동적 언어 지원 또는 COM 객체를 사용하여 코딩 할 때 더 적은 양의 코드를 작성해야하므로 유용합니다.
var : linq 쿼리에서 결과를 가져올 때 유용합니다. 3.5 프레임 워크에서는 linq 기능을 지원하기 위해 소개합니다.
참조 : 카운셀링
예:
Var strNameList=new List<string>(); By using this statement we can store list of names in the string format.
strNameList.add("Senthil");
strNameList.add("Vignesh");
strNameList.add(45); // This statement will cause the compile time error.
그러나 동적 형식에서는 기본 형식이 런타임에만 결정됩니다. 동적 데이터 형식은 컴파일 타임에 확인되지 않고 강력하게 형식화되지 않습니다. 동적 형식에 대한 초기 값을 할당 한 다음 새로운 형식으로 다시 할당 할 수 있습니다 수명 기간 동안의 가치.
예:
dynamic test="Senthil";
Console.Writeline(test.GetType()) // System.String
test=1222;
Console.Writeline(test.GetType()) // System.Int32
test=new List<string>();
Console.Writeline(test.GetType()) //System.Collections.Generic.List'1[System.String]
또한 linli를 사용하여 작업 할 때 더 나은 지원을 제공하지 않으며 람다 식, 확장 메서드 및 익명 메서드를 지원하지 않기 때문에 IntelliSense 지원도 제공하지 않습니다.
차이점은 다음과 같습니다.
var는 정적으로 유형이 지정되고 (컴파일 시간) 동적이 동적으로 유형이 지정됩니다 (런타임)
var로 선언 된 변수는 로컬에서만 사용할 수 있고 동적 변수는 매개 변수로 함수에 전달 될 수 있습니다 (함수 서명은 매개 변수를 var가 아닌 동적으로 정의 할 수 있음).
동적으로 속성의 분석은 런타임에 발생하며 var의 경우 컴파일 시간에 동적으로 선언 된 모든 변수가 존재하거나 존재하지 않을 수있는 메소드를 호출 할 수 있으므로 컴파일러는 오류를 발생시키지 않습니다.
var는 불가능하지만 동적으로는 가능합니다 (객체는 var가 아니라 동적으로 캐스팅 할 수 있음).
아룬 비자이라 하반