The Evolution of C# Part-II

2,579 views

Published on

사내 C# 세미나 Part-II 슬라이드입니다.
데모 코드는 https://github.com/gyuwon/csharp-seminar-demos/ 에 있습니다.

3.0
- Type Inference
- Anonymous Classes
- Extension Methods
- Lambda Expressions
- Expression Trees
- Linq
- IQueryable
- OData

4.0
- Static Typing vs. Dynamic Typing
- var vs. dynamic
- System.Dynamic.ExpandoObject
- System.Dynamic.DynamicObject
- Optional Arguments
- Named Arguments
- Covariance & Contravariance

5.0
- Blocking Programming vs. Non-Blocking Programming
- Asynchronous Methods(async & await)
- Caller Information

Published in: Technology
0 Comments
10 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
2,579
On SlideShare
0
From Embeds
0
Number of Embeds
1,210
Actions
Shares
0
Downloads
32
Comments
0
Likes
10
Embeds 0
No embeds

No notes for slide

The Evolution of C# Part-II

  1. 1. The Evolution of C# 버전 별 주요 특징 이규원
  2. 2. 본 세미나의 목적 • C# 주요 변화과정 둘러보기 • Remind • 가려운 곳 긁기 • 2%
  3. 3. 본 세미나에서 다루는 것들 • C# 언어의 버전 별 발전 과정 • C# 언어와 밀접한 .NET Framework 특징 • C# 언어에 영향을 준 프로그래밍 언어들과의 비교
  4. 4. 본 세미나에서 다루지 않는 것들 • C# 언어의 기초적인 문법(if, foreach, using, try, lock, …) • C# 언어와 직접적으로 관련되지 않은 .NET Framework 특징 • C# 언어와 직접적으로 관련되지 않은 프레임워크(TPL, WCF, Entity Framework, …) • 응용프로그램 플랫폼(WPF, ASP.NET, …)
  5. 5. 발표자 • • • • • • • • • • 프로그래머 통계학 학사, 숭실대 (`97~`05) Visual Studio의 노예 현 프리랜서 위대한 ESM팀 소속 1989년 BASIC 입문 on Apple IIe 1991년 C 입문 on 8086 1992년 음주 입문 1997년 C++ & Java 입문 2005년 C# 입문 gyuwon@live.com http://justhackem.wordpress.com http://facebook.com/gyuwon.yi
  6. 6. Keywords 1.0 • Managed 2.0 • Generic 4.0 • Dynamic 5.0 • Async 3.0 • Linq
  7. 7. 3.0 All for Linq
  8. 8. Type Inference • 주변 문맥을 통해 형식을 추론 • 컴파일러에 의해 결정(not in Run-time) var obj = new DoYouThinkThatTheNameOfThisStructIsTooLong?(); Func<int, int> square = x => x * x; Expression<Func<int, int>> exp = x => x * x;
  9. 9. Anonymous Classes • • • • 컴파일러에 의해 자동으로 생성되는 클래스(not in Run-time) 속성만으로 구성 각 속성은 개체가 초기화될 때에만 설정 가능 ToString() var obj = new { Id = 1, Name = "Tony Stark", Email = "ironman@avengers.com" };
  10. 10. DEMO Generic Collections of Anonymously Typed Elements
  11. 11. Extension Methods • • • • 상속과 재 컴파일 없이 개체에 메서드를 추가 대상 형식의 공개된 멤버에만 접근 가능 인스턴스 메서드 문법을 사용하는 정적 클래스의 정적 메서드 첫 번째 매개변수를 this 키워드로 수식
  12. 12. Extension Methods public static class DoubleExtensions { public static double Cube(this double x) { return x * x * x; } public static double Pow(this double x, double y) { return Math.Pow(x, y); } } double x = 10; Console.WriteLine(x.Cube()); // 1000 Console.WriteLine(x.Pow(2.5)); // 316.227766016838
  13. 13. Lambda(λ) Expressions • Anonymous methods • Expression trees • Argument(s) => Body
  14. 14. Lambda(λ) Expressions Func<int, bool> func Func<int, bool> func Func<int, bool> func Func<int, bool> func Func<int, bool> func Expression<Func<int, = delegate(int n) { return n > 20; }; = (int n) => { return n > 20; }; = (int n) => n > 20; = (n) => n > 20; = n => n > 20; bool>> expression = n => n > 20;
  15. 15. Expression Trees • 트리 like 자료구조로 코드를 표현 • ≠ Delegate • 컴파일러에 의해 생성 • Expression API를 사용한 구성 • IQueryable<> • DLR
  16. 16. Expression Tree Decomposition Expression<Func<int, bool>> expression = n => n > 20; expression: Lambda Expression Parameters Body : BinaryExpression Type = System.Boolean NodeType = GreaterThan Left Right : ParameterExpression Name = “n” Type = System.Int32 ConstantExpression Value = 20
  17. 17. Expression Tree Composition ParameterExpression n = Expression.Parameter(typeof(int), "n"); ConstantExpression twenty = Expression.Constant(20); BinaryExpression nGreaterThanTwenty = Expression.GreaterThan(n, twenty); var expression = Expression.Lambda<Func<int, bool>>(nGreaterThanTwenty, n); Console.WriteLine(expression); Func<int, bool> func = expression.Compile(); Console.WriteLine(func(10)); // Output // n => (n > 20) // False
  18. 18. Linq • Language Integrated Query • 프로그래밍 세계와 데이터 세계를 연결 • [lɪŋk] • 프로그래밍 언어로 데이터 처리 • 지연된 실행 • Fluent api • Query expression
  19. 19. Query Expression vs. Fluent Api Query Expression from c in contacts where c.Species == "Human" orderby c.Name select c; Fluent Api contacts .Where(c => c.Species == "Human") .OrderBy(c => c.Name);
  20. 20. Query Expression vs. Fluent Api Query Expression from s in strings let split = s.Split(' ') where split.Length >= 2 && split[0][0] == split[1][0] orderby split[1] select s; Fluent Api strings .Select(s => new { Split = s.Split(' '), String = s }) .Where(e => e.Split[0][0] == e.Split[1][0]) .OrderBy(e => e.Split[1]) .Select(e => e.String);
  21. 21. DEMO Query Expression vs. Fluent Api Custom Query Operation
  22. 22. Count() vs. Any() Do not if (s.Count() == 0) … if (s.Count() != 0) … Do if (s.Any() == false) … if (s.Any()) … O(1) or O(n) O(1)
  23. 23. DEMO Count() vs. Any()
  24. 24. IQueryable • Expression Tree로 표현되는 질의 명령 • 명령을 번역하고 실행하는 QueryProvider • QueryProvider의 핵심 코드는 데이터 제공자에 의해 구현
  25. 25. IQueryable API System.Linq.Enumerable public static IEnumerable<TSource> Where<TSource>( this IEnumerable<TSource> source, Func<TSource, bool> predicate) System.Linq.Queryable public static IQueryable<TSource> Where<TSource>( this IQueryable<TSource> source, Expression<Func<TSource, bool>> predicate)
  26. 26. IQueryable Data Provider Data Source Data Command Data Consumer Queryable Programming Language Expression Tree Query Provider
  27. 27. Programming Language var query = from c in db.Contacts where c.Id == id select c;
  28. 28. Expression Tree Query Expression Method MethodCallExpressionN Where Arguments 0 {db.Contacts}: ObjectQuery 1 LogicalBinaryExpression Left {c.Id} : PropertyExpression Right {id} NodeType Equal
  29. 29. Data Command SELECT [Extent1].[Id] AS [Id], [Extent1].[FirstName] AS [FirstName], [Extent1].[LastName] AS [LastName], [Extent1].[Email] AS [Email] FROM [dbo].[Contacts] AS [Extent1] WHERE ([Extent1].[Id] = @p__linq__0) AND (@p__linq__0 IS NOT NULL)
  30. 30. DEMO IQueryable
  31. 31. OData • 데이터 처리를 위한 웹 프로토콜 • http://www.odata.org • ASP.NET Web API [Queryable] public IQueryable<…> …()
  32. 32. OData /api/Contacts/ SELECT [Extent1].[Id] AS [Id], [Extent1].[FirstName] AS [FirstName], [Extent1].[LastName] AS [LastName], [Extent1].[Email] AS [Email] FROM [dbo].[Contacts] AS [Extent1]
  33. 33. OData /api/Contacts/?$filter=length(FirstName) le 4 SELECT [Extent1].[Id] AS [Id], [Extent1].[FirstName] AS [FirstName], [Extent1].[LastName] AS [LastName], [Extent1].[Email] AS [Email] FROM [dbo].[Contacts] AS [Extent1] WHERE (CAST(LEN([Extent1].[FirstName]) AS int)) <= @p__linq__0
  34. 34. DEMO OData
  35. 35. Take a break
  36. 36. 4.0 Dynamic Default Parameters and Name Arguments Covariance and Contravariance
  37. 37. Static Typing vs. Dynamic Typing Static Typing • 컴파일 타임 형식 검사 • 개체가 생성될 때 형식 결정 Dynamic Typing • 런타임 형식 검사 • 런타임 속성 및 행위 변경 • 안정성 증대 • 성능 최적화 • 쉽고 빠른 코드 수정 • 낮은 결합도 • 단위 테스트를 통한 오류 검출
  38. 38. Dynamic in C# • “dynamic” 키워드 • 동적 언어의 특징 부여 • 정적 형식 개체의 동적 멤버 바인딩 • System.Dynamic.ExpandoObject • System.Dynamic.DynamicObject
  39. 39. var vs. dynamic • Anonymous Types dynamic • Dynamic Typing • 내부적으로 System.Object • IntelliSense • 런타임 변수 형식 변경 불가 • 명시적 형 변환 없는 멤버 접근 • 런타임 변수 형식 변경 가능 var • 컴파일러에 의해 형식 유추
  40. 40. DEMO Dynamic Binding of Statically Typed Objects
  41. 41. ExpandoObject • 런타임 멤버 추가 및 삭제 • Hashing • sealed • 문자열 키 사전 기반 자료구조 대안
  42. 42. DEMO ExpandoObject
  43. 43. DynamicObject • 동적 개체 구현 기반 클래스 • Interoperation • public virtual bool Try…(…Binder binder, …)
  44. 44. Static Type Casting Hell private void SomeMethod1(Geometry geometry) { BezierSegment bezier = (BezierSegment)((PathGeometry)((CombinedGeometry)geometry).Geometry1).Figur es[0].Segments[0]; } private void SomeMethod2(dynamic geometry) { BezierSegment bezier = geometry.Geometry1.Figures[0].Segments[0]; }
  45. 45. 선택적 매개변수(Optional Arguments) • 기본값을 가진 매개 변수 • 상수 식 또는 값 형식 기본 값 • 선택적 매개변수는 모든 필수적 매개변수 뒤에 위치
  46. 46. 명명된 매개변수(Named Arguments) • 이름을 사용한 인수 전달 • 매개변수 순서에 구애 받지 않음 • 명명된 매개변수는 모든 위치 기반 매개변수 뒤에 위치
  47. 47. DEMO Optional Arguments and Named Arguments
  48. 48. Covariance • <out T> • If A → B • IEnumerable<A> → IEnumerable<B>
  49. 49. Contravariance • <in T> • If A → B • Action<B> → Action<A>
  50. 50. Covariance and Contravariance • 인터페이스와 대리자 대상 • 참조 형식 형식 매개변수에만 적용 가능
  51. 51. DEMO Covariance & Contravariance
  52. 52. Take a break
  53. 53. 5.0 Asynchronous Caller Information
  54. 54. Blocking Manner Working Request External Service Waiting Response Working
  55. 55. Non-Blocking Manner in Client-Side Main Thread Working Request Working User Interaction Working Working Working Dispatch Response External Service
  56. 56. Non-Blocking Manner in Server-Side Request Working Request Thread Pool External Service Response Working Response
  57. 57. Blocking vs. Non-Blocking with TPL Blocking semantics int x = rs.Compute(rs.Get(key)); Console.WriteLine(x); Rocks or Sucks? Non-blocking semantics rs.GetAsync(key) .ContinueWith(t1 => rs.ComputeAsync(t1.Result) .ContinueWith(t2 => Console.WriteLine(t2.Result)));
  58. 58. Through await Keyword Blocking semantics int x = rs.Compute(rs.Get(key)); Console.WriteLine(x); Rocks! Non-blocking semantics with await keyword int x = await rs.ComputeAsync(await rs.GetAsync(key)); rs.Compute rs.ComputeAsync( ( rs.Get (key)); Console.WriteLine(x);
  59. 59. Asynchronous Methods async void/Task/Task<…> …(…) { … … await [Awaitable Statement] … }
  60. 60. Awaitable • GetAwaiter() • INotifyCompletion { void OnCompleted(Action continuation); } • bool IsCompleted { get; } • GetResult() • Task or Task<>
  61. 61. DEMO Asynchronous Manner Client Application Non-blocking Web Api
  62. 62. await 문법 조합 try using (res) if (…) foreach (var e in …) { { { { … … await … await … } await … … … … … } catch { } } … await … }
  63. 63. Caller Infomation • • • • CallerMemberNameAttribute CallerFilePathAttribute CallerLineNumberAttribute 컴파일러 서비스
  64. 64. INotifyPropertyChanged in C# 1.0 private int _value;  오류 가능성 public int Value {  Refactoring 어려움 get { return this._value; } set { this._value = value; this.OnPropertyChanged("Value"); } } public event PropertyChangedEventHandler PropertyChanged; protected virtual void OnPropertyChanged(string propertyName) { if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); }
  65. 65. INotifyPropertyChanged in C# 3.0 private int _value;  비교적 높은 비용 public int Value {  하지만 refactorable get { return this._value; } set { this.Set(() => this.Value, ref this._value, value); } } public event PropertyChangedEventHandler PropertyChanged; protected void Set<T>(Expression<Func<T>> expression, ref T field, T newValue) { var body = expression.Body as MemberExpression; string propertyName = body.Member.Name; field = newValue; if (this.PropertyChanged != null) this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); }
  66. 66. INotifyPropertyChanged in C# 5.0 private int _value;  낮은 비용 public int Value {  Refactorable get { return this._value; } set { this.Set(ref this._value, value); } } public event PropertyChangedEventHandler PropertyChanged; protected void Set<T>(ref T field, T newValue, [CallerMemberName]string propertyName = null) { field = newValue; if (this.PropertyChanged != null) this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); }
  67. 67. QnA
  68. 68.  감사합니다 

×