Introduction
C#는 주로 statically typed language이다. 변수의 data type을 compiler가 미리 알아야 한다.
변수의 data type을 알지 못하면, compiler는 compile하지 않고, 에러를 발생시킨다.
.NET 4.0에 DLR(Dynamic Language Runtime)이 추가된 이후, C#도 dynamic feature를 제공한다.
System.Dynamic Namespace에는 DynamicObject Class와 ExpandoObject Class를 포함한다.
Dynamic Data Type
외부 파일의 데이터를 C# code로 변환하는 경우, C#은 외부 파일 데이터의 타입을 알지 못한다.
이런 경우, dynamic type을 사용해서 compile time에서의 data type checking을 피할 수 있다. 또한 runtime에서 type을 변경할 수도 있다.
Dynamic Objects
코드 작성 시, object를 사용해야 할 경우 일반적으로 class를 만들고 properties와 methods를 추가한다. 그 다음 해당 class의 object를 생성하고 property를 set 하고 method를 invoke한다.
하지만 때때로, 동적으로 object를 추가하고 properties를 set 해야 하는 경우가 있다.
즉, compiler가 class의 properties나 method의 checking하는 것을 피해야 한다.
ASP.NET MVC의 ViewBag이 controller class에서 사용하는 dynamic object이다.
ViewBag object는 임의의 값을 저장하여 View로 전달한다. ViewBag은 정의된 어떠한 property도 없다.
동적으로 property를 추가할 수 있다.
System.Dynamic namespace는 dynamic objects를 생성할 수 있는 2개의 class를 제공한다.
ExpandoObject Class와 DynamicObject Class이다. 모두 IDynamicMetaObjectProvider interface를 구현한다.
ExpandoObject Class
C#에서는 JavaScript와 비슷하게, dynamic object를 생성할 수 있도록 한다.
ExpandoObject Class는 sealed이라서 상속받을 수 없다.
using System.Dynamic;
dynamic d;
d = new ExpandoObject();
d.FirstName = "Tom";
d.LastName = "Jerry";
d.BirthDate = new DateTime(1960, 12, 01);
Func<string, string, string> method = (a, b) => a + " " + b;
d.GetData = method;
Console.WriteLine(d.FirstName + " " + d.LastName + "..." + d.GetData("Tom", "Jerry") + " - " + d.GetType());
출력 :
Tom Jerry...Tom Jerry - System.Dynamic.ExpandoObject
DynamicObject Class
DynamicObject Class를 사용하여 dynamic object를 만들기 위해서는, DynamicObject를 상속받고 3개의 methods를 override해야 한다.
ExpandoObject Class에 비해 코드 작성이 더 필요하지만, dynamic object의 properties, methods의 정밀한 제어가 가능하다.
TryGetMember, TrySetMember, TryInvokeMember
using System.Dynamic;
dynamic d;
d = new Employee();
d.FirstName = "Tom";
d.LastName = "Jerry";
d.BirthDate = new DateTime(1960, 12, 01);
Func<string, string, string> method = (a, b) => a + " " + b;
d.GetData = method;
Console.WriteLine(d.FirstName + " " + d.LastName + "..." + d.GetData("Tom", "Jerry") + " - " + d.GetType());
public class Employee : DynamicObject
{
Dictionary<string, object> properties = new Dictionary<string, object>();
public override bool TryGetMember(GetMemberBinder binder, out object result)
{
if (properties.ContainsKey(binder.Name))
{
result = properties[binder.Name];
return true;
}
else
{
result = "Invalid Property!";
return false;
}
}
public override bool TrySetMember(SetMemberBinder binder, object value)
{
properties[binder.Name] = value;
return true;
}
public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result)
{
dynamic method = properties[binder.Name];
result = method(args[0].ToString(), args[1].ToString());
return true;
}
}
출력 :
Tom Jerry...Tom Jerry - Employee
'C#' 카테고리의 다른 글
C#] 반복자(Iterator), yield keyword (0) | 2022.07.19 |
---|---|
C#] Delegates, Anonymous Methods and Lambda Expressions (0) | 2022.07.18 |
C#] Expression trees 설명, Delegate와 차이점 (0) | 2022.07.06 |
C#] Delegates (0) | 2022.07.06 |
C#] 코드 성능 분석 BenchmarkDotNet (0) | 2022.07.05 |
댓글