2009-08-18 3 views
21

C# 4에는 동적 언어 기능을 C#으로 가져 오는 새로운 dynamic 키워드가 포함됩니다.C# 4 동적 유형은 어떻게 사용합니까?

자신의 코드에서 어떻게 사용 하시겠습니까? 어떤 패턴을 제안 하시겠습니까? 현재 프로젝트의 어느 부분에서 코드를보다 깔끔하고 단순하게 만들거나 단순히 할 수없는 일을 가능하게 할 것입니까? (IronRuby 또는 IronPython과 같은 동적 언어를 사용하는 명백한 상호 운용성 제외)?

추신 :이 C# 4 추가가 마음에 들지 않으시면 부정적으로 의견을 부탁하지 마십시오.

편집 : 질문 다시 게시.

동적의 고전적인 사용법은 대부분의 stackoverflow C 사용자가 잘 알고 있습니다. C#의 정신을 너무 많이 잃지 않고 동적으로 유용하게 활용할 수있는 새로운 C# 패턴을 생각해 보면 알고 싶습니다.

+0

중복 질문이 있으십니까? http://stackoverflow.com/questions/244302/what-do-you-think-of-the-new-c-4-0-dynamic-keyword – Lazarus

+0

을 참조하십시오. 질문은 '좋아하지 않습니다. 그것? ' 그러나 당신은 그것을 어떻게 할 것인가? 그러나 사실 아주 가까운 것입니다. 나는 비슷한 질문에 대한 검색을했지만 이것에 걸리지 않았습니다. – thinkbeforecoding

+3

이것은 "올바른"대답이없는 토론입니다. 따라서 커뮤니티 위키 여야합니다. – ryeguy

답변

1

필자가 호출 할 멤버를 지정하기 전에 COM/Interop을 다루는 코드를 단순화하기 위해이 매개 변수를 사용합니다 (기본적으로 컴파일러는 함수의 존재에 대해 알지 못했지만 컴파일 타임에 그것을 기술 할 필요가있다). 동적 인 경우이 작업이 덜 복잡해지며 코드가 가벼워집니다.

+0

Interop을 간소화 할 수있는 유용한 블로그 항목 및 코드는 다음에서 찾을 수 있습니다. http://tirania.org/blog/archive/2009/Aug-11.html – Yakeen

12

구식 반사가 사용되며 코드 가독성이 저하되는 곳이면 어디에서나 사용할 수 있습니다. 그리고, 당신이 말했듯이, Interop의 일부 시나리오 (저는 때때로 COM과 함께 작업합니다).

꽤 많이 있습니다. dynamic 사용을 피할 수 있으면 피해야합니다. 컴파일 시간 검사, 성능 등

몇 주 전, 나는 this article을 기억했다. 처음 읽었을 때, 나는 솔직히 사과를 받았다. 그러나 내가 깨닫지 못한 것은 내가 심지어 알 수없는 유형의 연산자를 사용하는 방법을 모른다는 것입니다. 생성 된 코드가 다음과 같이 될지 궁금해하기 시작했습니다.

dynamic c = 10; 
int b = c * c; 

정규 반영을 사용하면 정의 된 연산자를 사용할 수 없습니다. Microsoft 네임 스페이스의 일부 내용을 사용하여 코드가 상당히 생성되었습니다. 위의 코드가 읽기 쉽다는 것을 말합시다. 작동하는 것이 좋습니다.하지만 역시 입니다. 느림 : 일반적인 곱셈 (doh)보다 약 10,000 배 느리고 ICalculator 인터페이스보다 약 100 배 느립니다. Multiply 메서드 사용.

편집 - 생성 된 코드, 관심있는 사람들을위한 :

if (<Test>o__SiteContainer0.<>p__Sitea == null) 
    <Test>o__SiteContainer0.<>p__Sitea = 
    CallSite<Func<CallSite, object, object, object>>.Create(
     new CSharpBinaryOperationBinder(ExpressionType.Multiply, 
     false, false, new CSharpArgumentInfo[] { 
      new CSharpArgumentInfo(CSharpArgumentInfoFlags.None, null), 
      new CSharpArgumentInfo(CSharpArgumentInfoFlags.None, null) })); 
b = <Test>o__SiteContainer0.<>p__Site9.Target(
     <Test>o__SiteContainer0.<>p__Site9, 
     <Test>o__SiteContainer0.<>p__Sitea.Target(
     <Test>o__SiteContainer0.<>p__Sitea, c, c)); 
+0

리플렉션을 동적으로 대체 할 수있는 경우를 생각해 봅니다. 코드, 샘플을 줄 수 있습니까? – thinkbeforecoding

+0

@Think : 함수가 반사적으로 호출되는 경우에 사용할 수 있습니다. 접근성을 무시하기 위해 반사가 사용되는 경우는 사용할 수 없습니다 (처음에는 객체에 캐스트했거나 확실하지 않은 경우 제외 ...). 검사를 수행해야합니다. . –

7

동적 키워드가 모두 두 가지 시나리오에 필요한 코드를 단순화에 대한된다

  • C 번호를 상호 운용성
  • 를 COM하기 C#에서 동적 언어 (JavaScript 등) interop

은 시나리오 외에서 사용할 수 있지만 이 아니어야합니다.

+0

두 번째 질문에 대한 정보가 더 있으십니까? C#으로 관리되는 게임 엔진 - ajax 그래픽 엔진에 노출되는 것은 제가 작업 중이며 이것이 도움이 될만한 방법을보고 싶습니다! – divinci

4

미구엘 드 이카는 자신의 블로그에 아주 멋진 사용 사례를 제시 here (소스 포함) : 그것은 안전하고 신뢰할 수있는 방법으로이 작업을 수행 할 수 있다면

dynamic d = new PInvoke ("libc"); 
d.printf ("I have been clicked %d times", times); 

, 즉 기본에 대한 좋지 않을까 코드 interop.

3

이것은 또한 우리가

public class MySpecialFunctions 
{ 
    public void Execute(int x) {...} 
    public void Execute(string x) {...} 
    public void Execute(long x) {...} 
} 

dynamic x = getx(); 
var myFunc = new MySpecialFunctions(); 
myFunc.Execute(x); 

... 실행시 가장 좋은 방법 일치 호출 지금 가능합니다 멀티 파견 등의 특정 경우에 방문자 패턴을 사용하는 데, 대신에되는 일을 방지 할 수 있습니다 컴파일시에 해결됨

+0

여기서 이점을 이해할 수 있도록 도와주세요. 왜 이것이 컴파일 시간에 해결되지 않기를 바라겠습니까? – Jake

+0

때로는 어떤 유형으로 작업하는지 알지 못하는 경우가 있습니다. 예를 들어 기본 클래스로 작업하고 있지만 하위 유형에 특수한 동작이 필요한 경우가 있습니다. 트리 구조를 가로 지르는 경우 각 노드는 기본 클래스 노드를 상속 할 수 있지만 노드를 처리 할 때는 부속 유형 (예 : 복합 노드)에 대한 특정 동작이 필요합니다. MySpecialFunctions와 같은 클래스를 활용할 수 있으며, 거대한 switch/if 블록없이 Execute를 호출하여 처리 할 노드의 유형을 검사하여 호출 할 메소드를 찾으려고 할 수 있습니다. 클라이언트 코드는 MySpecialFunctions를 올바르게 사용하기 위해 모든 부속 유형을 인식하지 않아도됩니다. – saret

+0

또한 MySpecialFunctions의 새/대체 부속 유형은 클라이언트 코드를 처리하는 노드를 변경할 필요가 없습니다. – saret

5

최근에 C# 4.0의 동적 유형에 대해 블로그를 작성했으며 그 중에서도 잠재적 인 용도와 함정 중 일부를 언급했습니다. 기사 자체가 너무 커서 여기에 적합하지 않지만이 address에서 전체 기사를 읽을 수 있습니다. 동적 C#을 객체로 임의의 XML 또는 JSON을 읽는

  • : 요약으로

    , 여기에 몇 가지 유용한 사용 (IronPython의 같은 COM 라이브러리와 동적 언어와 interoping의 명백한 제외)의 경우이다. .Net 프레임 워크에는 XML 및 JSON 문서를 C# 객체로 쉽게 deserialize하기위한 클래스 및 속성이 포함되어 있지만 구조가 정적 인 경우에만 가능합니다. 동적 인 경우 런타임에 필드를 검색해야 할 경우 동적 객체로만 직렬화를 해제 할 수 있습니다. .Net은 기본적으로이 기능을 제공하지는 않지만 jsonfx 또는 DynamicJson
  • 과 같은 타사 도구를 통해 메소드에서 익명 유형을 반환 할 수 있습니다. 익명 형식은 범위가 정의 된 메서드에 제한되지만 동적 인 도움으로이를 극복 할 수 있습니다. 물론 동적 인 구조 (컴파일 타임 검사없이)로 객체를 노출 할 것이기 때문에 이것은 위험한 일입니다. 그러나 어떤 경우에는 유용 ​​할 수 있습니다. 예를 들어 다음과 같은 방법은 SQL Linq에를 사용하여 DB 테이블에서 두 컬럼을 읽고 결과를 반환합니다

    public static List<dynamic> GetEmployees() 
    { 
        List<Employee> source = GenerateEmployeeCollection(); 
        var queyResult = from employee in source 
           where employee.Age > 20 
           select new { employee.FirstName, employee.Age }; 
    
        return queyResult.ToList<dynamic>(); 
    } 
    
  • 동적 데이터를 반환 REST WCF 서비스를 만들 수 있습니다. 이는 다음 시나리오에서 유용 할 수 있습니다. 사용자 관련 데이터를 반환하는 웹 메소드가 있다고 가정합니다. 그러나 귀하의 서비스는 사용자에 관한 많은 정보를 제공하며 항상 모든 정보를 반환하는 것은 효율적이지 않습니다. 당신은 소비자들이 실제로 다음 URL을 필요 같은 필드를 지정할 수 있도록 할 수있을 것입니다 경우 그것은 더 나은 것

    http://api.example.com/users?userId=xxxx&fields=firstName,lastName,age 
    

    문제는 다음 WCF는 밖으로 만든 클라이언트의 응답으로 돌아갑니다 사실에서 온다 직렬화 된 객체의 객체가 정적 인 경우 동적 응답을 반환 할 방법이 없으므로 동적 유형을 사용해야합니다. 그러나 여기서 마지막으로 하나의 문제가 있습니다. 즉, 기본적으로 동적 유형은 직렬화 할 수 없습니다. article에는 이것을 극복하는 방법을 보여주는 코드 샘플이 있습니다 (다시 한 번 그 크기 때문에 게시하지 않습니다).

결국 내가 언급 한 두 가지 사용 사례에는 몇 가지 대안이나 타사 도구가 필요합니다. .NET 팀이 프레임 워크에 매우 멋진 기능을 추가했지만 COM 및 동적 언어 interop를 염두에두고 추가했을 수도 있습니다.역동적 인 언어는 강력한 장점을 가지고 있기 때문에 부끄러운 일이 될 수 있으며 강력한 형식 언어의 강점을 가진 플랫폼에 제공하면 닷넷과 C#을 다른 개발 플랫폼보다 앞서게 될 것입니다.

관련 문제