Section 35.4: 컴파일 시점에는 알 수 없는 특정 타입 처리하기

아래의 두 클래스는 동일한 결과를 보여준다:

class IfElseExample { public string DebugToString(object a) { if (a is StringBuilder) { return DebugToStringInternal(a as StringBuilder); } else if (a is List < string > ) { return DebugToStringInternal(a as List < string > ); } else { return a.ToString(); } } private string DebugToStringInternal(object a) { // Fall Back return a.ToString(); } private string DebugToStringInternal(StringBuilder sb) { return $"StringBuilder - Capacity: {sb.Capacity}, MaxCapacity: {sb.MaxCapacity}, Value: {sb.ToString()}"; } private string DebugToStringInternal(List < string > list) { return $"List<string> - Count: {list.Count}, Value: {Environment.NewLine + "\t " + string.Join(Environment.NewLine + "\t ", list.ToArray())}"; } } class DynamicExample { public string DebugToString(object a) { return DebugToStringInternal((dynamic) a); } private string DebugToStringInternal(object a) { // Fall Back return a.ToString(); } private string DebugToStringInternal(StringBuilder sb) { return $"StringBuilder - Capacity: {sb.Capacity}, MaxCapacity: {sb.MaxCapacity}, Value: {sb.ToString()}"; } private string DebugToStringInternal(List < string > list) { return $"List<string> - Count: {list.Count}, Value: {Environment.NewLine + "\t " + string.Join(Environment.NewLine + "\t ", list.ToArray())}"; } }

위 예제에서 dynamic 을 사용시의 장점은, 처리를 위한 새로운 타입을 추가하고자 할 때, DebugToStringInternal 메소드에 해당 타입에 대한 overload 만 하나 추가해주면 된다는 점이다. 이는 해당 메소드 호출 시 일일이 원하는 타입으로 타입 변환 (cast) 을 할 필요가 없다는 추가적인 장점이 있다.

본 문서는 C# Notes for Professionals (라이센스:CC-BY-SA) 를 한글로 번역한 문서입니다. 번역상 오류가 있을 수 있으므로 정확한 내용은 원본 문서를 참고하세요.

[출처] https://books.goalkicker.com/CSharpBook/

반응형

Section 35.3: dynamic 반환하기

using System; public static void Main() { var value = GetValue(); Console.WriteLine(value); // dynamics are useful! 이 출력된다 } private static dynamic GetValue() { return "dynamics are useful!"; }

역주 : value 변수의 타입을 var 가 아닌 dynamic 으로 선언해도 결과는 동일합니다.

본 문서는 C# Notes for Professionals (라이센스:CC-BY-SA) 를 한글로 번역한 문서입니다. 번역상 오류가 있을 수 있으므로 정확한 내용은 원본 문서를 참고하세요.

[출처] https://books.goalkicker.com/CSharpBook/

반응형

Section 35.2: dynamic 변수 생성하기

dynamic foo = 123; Console.WriteLine(foo + 234); // 357 Console.WriteLine(foo.ToUpper()); // int 는 ToUpper 메소드를 지원하지 않으므로 RuntimeBinderException 이 발생된다 foo = "123"; Console.WriteLine(foo + 234); // 123234 Console.WriteLine(foo.ToUpper()); // 이번엔 exception 이 발생되지 않는다
본 문서는 C# Notes for Professionals (라이센스:CC-BY-SA) 를 한글로 번역한 문서입니다. 번역상 오류가 있을 수 있으므로 정확한 내용은 원본 문서를 참고하세요.

[출처] https://books.goalkicker.com/CSharpBook/

반응형

Section 35.1: 속성 (property) 을 갖는 dynamic 객체 생성하기

using System; using System.Dynamic; dynamic info = new ExpandoObject(); info.Id = 123; info.Another = 456; Console.WriteLine(info.Another); // 456 Console.WriteLine(info.DoesntExist); // RuntimeBinderException 을 발생시킨다 (throw)
본 문서는 C# Notes for Professionals (라이센스:CC-BY-SA) 를 한글로 번역한 문서입니다. 번역상 오류가 있을 수 있으므로 정확한 내용은 원본 문서를 참고하세요.

[출처] https://books.goalkicker.com/CSharpBook/

반응형

Section 34.6: 묵시적 타입의 배열

이름이 없는 (anonymous) 타입에 대한 배열은 묵시적 타입 지정 (implicit typing) 을 통해 생성할 수 있다.

var arr = new[] { new { Id = 0 }, new { Id = 1 } };
본 문서는 C# Notes for Professionals (라이센스:CC-BY-SA) 를 한글로 번역한 문서입니다. 번역상 오류가 있을 수 있으므로 정확한 내용은 원본 문서를 참고하세요.

[출처] https://books.goalkicker.com/CSharpBook/

반응형

Section 34.5: Generic 타입을 익명 (anonymous) 타입으로 인스턴스 생성하기 (instantiate)

아래 예제와 같이, generic 생성자의 타입 파라미터에 사용된 익명 타입이 리턴 타입 이름에 기술되여야 하는 경우가 생길 수 있으며, 이는 실제적으로 가능하지 않다. 대신에, 타입 추론을 사용하게 함으로써 generic 메소드를 사용할 수 있다.

var anon = new { Foo = 1, Bar = 2 }; var anon2 = new { Foo = 5, Bar = 10 }; List<T> CreateList<T>(params T[] items) { return new List<T>(items); } var list1 = CreateList(anon, anon2);

묵시적 타입 배열의 경우에는 ToList LINQ 메소드를 사용하여 List<T> 로 변환이 가능하다:

var list2 = new[] {anon, anon2}.ToList();
본 문서는 C# Notes for Professionals (라이센스:CC-BY-SA) 를 한글로 번역한 문서입니다. 번역상 오류가 있을 수 있으므로 정확한 내용은 원본 문서를 참고하세요.

[출처] https://books.goalkicker.com/CSharpBook/

반응형

Section 34.4: Generic 메소드에 익명 타입 사용하기

Generic 메소드는 타입 추론을 통해 익명 타입 역시 사용 가능하도록 지원하고 있다.

void Log<T>(T obj) { // ... } Log(new { Value = 10 });

이는 LINQ 표현식 (expression) 역시 익명 타입과 함께 사용될 수 있음을 의미한다:

var products = new[] { new { Amount = 10, Id = 0 }, new { Amount = 20, Id = 1 }, new { Amount = 15, Id = 2 } }; var idsByAmount = products.OrderBy(x => x.Amount).Select(x => x.Id); // idsByAmount: 0, 2, 1
본 문서는 C# Notes for Professionals (라이센스:CC-BY-SA) 를 한글로 번역한 문서입니다. 번역상 오류가 있을 수 있으므로 정확한 내용은 원본 문서를 참고하세요.

[출처] https://books.goalkicker.com/CSharpBook/

반응형

Section 34.3: 익명 (anonymous) 타입의 동일성 (equality)

익명 (anonymous) 타입의 동일성 (equality) 은 Equals 인스턴스 메소드를 통해 결정된다. 두 객체가 모든 속성들에 대하여 동일한 타입과 값을 가질 경우 (a.Prop.Equals(b.Prop) 를 통해) 둘은 동일하다고 간주된다.

var anon = new { Foo = 1, Bar = 2 }; var anon2 = new { Foo = 1, Bar = 2 }; var anon3 = new { Foo = 5, Bar = 10 }; var anon3 = new { Foo = 5, Bar = 10 }; var anon4 = new { Bar = 2, Foo = 1 }; // anon.Equals(anon2) == true // anon.Equals(anon3) == false // anon.Equals(anon4) == false (anon 과 anon4 는 다른 타입을 가진다, 아래 설명을 참고한다)

두 익명 타입은 타입의 각 속성들이 동일한 이름과 타입, 그리고 동일한 순서로 나타났을때에만 동일하다고 간주된다.

var anon = new { Foo = 1, Bar = 2 }; var anon2 = new { Foo = 7, Bar = 1 }; var anon3 = new { Bar = 1, Foo = 3 }; var anon4 = new { Fa = 1, Bar = 2 }; // anon 과 anon2 는 동일한 타입을 갖는다 // anon 과 anon3 는 다른 타입을 갖는다 (Bar 와 Foo 가 나타난 순서가 다르다) // anon 과 anon4 는 다른 타입을 갖는다 (속성 이름이 다르다)
본 문서는 C# Notes for Professionals (라이센스:CC-BY-SA) 를 한글로 번역한 문서입니다. 번역상 오류가 있을 수 있으므로 정확한 내용은 원본 문서를 참고하세요.

[출처] https://books.goalkicker.com/CSharpBook/

반응형

+ Recent posts