Windows Phone 72012.01.19 16:19

일을 하다보면 반복적인 일을 하게 된다.

예를 들면

List<MovieInfo> mi = new List<MovieInfo>();
foreach (var item in e.XmlData["rcpt_infos"] as List<Dictionary<string,object>>)
                {
                    mi.Add(new MovieInfo()
                    {
                        h_pstr_img_adr = item["h_pstr_img_adr"] as string,
                        h_abrd_dt = item["h_abrd_dt"] as string,
                        h_movie_ttl = item["h_movie_ttl"] as string,
                        h_movie_knd = item["h_movie_knd"] as string,
                        h_movie_dirtor = item["h_movie_dirtor"] as string,
                        h_movie_actor = item["h_movie_actor"] as string,
                        h_see_cl = item["h_see_cl"] as string,
                        h_scrn_tm = item["h_scrn_tm"] as string,
                        h_movie_fare = item["h_movie_fare"] as string,
                    });
                }

이코드는 xml을 읽어서 GenericList에 넣는 구문이다.

xml은 dictionary로 되어 있어서 저렇게 item[키값] 으로 넣어줘야 한다. 하지만 저것도 한두번이지

xml을 읽어오는 족족 저런 구문을 써야 한다면 코드는 늘어날것이고 유지보수 하는 사람과 코드를 짜는 사람

모두 짜증나게된다.

자 그러면 어떻게 할것인가? 저 코드를 단번에 줄여보자.

일단 MovieInfo라는 Model에는

public class MovieInfo
    {
        /// <summary>
        /// 영화 이미지
        /// </summary>
        public string h_pstr_img_adr { get; set; }

        /// <summary>
        /// 승차일
        /// </summary>
        public string h_abrd_dt { get; set; }

.

.

.

 

머 대충 이렇게 만들어졌다. 모두 string이다.

이 properties를 한번에 읽어서 set할것이다.

기존 방식은 위에처럼 mi.add(new Moveiinfo() { h_psr_img_.. = “흑흑”}); 머이렇게 반복적인 작업이 아닌 자동으로 해보자.

일단 propeties는 type으로 부터 얻어와야 한다. 간략한 예제를 보자.

MovieInfo m = new MovieInfo();
var temp = (m.GetType()).GetProperties();
temp[0].SetValue(m, "hello", null);

너무 간략하다. 코드를 설명하자면 퍼로퍼티 리스트를 가져와서 첫번째(맨위에 있는 h_pstr_img_adr)에 string 을 set한다.

원리를 알았으니  이제 맨위의 코드를 줄여보자.

자 첫번째로 줄인것이다.

 

List<MovieInfo> mi = new List<MovieInfo>();
foreach (var item in e.XmlData["rcpt_infos"] as List<Dictionary<string,object>>)
{
    MovieInfo m = new MovieInfo();
    var properties = ((new MovieInfo()).GetType().GetProperties());
    foreach (var p in properties)
    {
        p.SetValue(m, item[p.Name], null);
    }
    mi.Add(m);
}

처음에 코드랑 비교가 되는가? 노가다가 많이 줄어들었다. 하지만 이코드를 재사용할수가 없다는 단점이 있다.

왜냐하면 MovieInfo때문에.. 그렇다면 최대한 재사용을 해서 메소드를 짜보자.

 

private static object GetModelData(object o , Dictionary<string, object> item)
{
    Object m = Convert.ChangeType(o, o.GetType(), null);

    var properties = m.GetType().GetProperties();

    foreach (var p in properties)
    {
        p.SetValue(m, item[p.Name], null);
    }
    return m;
}
이건 구현부분
List<MovieInfo> mi = new List<MovieInfo>();
foreach (var item in e.XmlData["rcpt_infos"] as List<Dictionary<string,object>>)
{
    MovieInfo m = new MovieInfo();
    mi.Add(GetModelData(m, item) as MovieInfo);
}

자 이건 어떤가? 단 두줄로 끝나버렸다. 그리고 재사용까지 가능하다.

원리는 Object로 해당 Model 즉 MovieInfo를 넘기고 메소드안에서 casting한다.

Object m = Convert.ChangeType(o, o.GetType(), null);

이런식으로.  이렇게 되면 object m은 MovieInfo로 형변환이 완료 된것이다.

보이는가?  맨위의 지저분한 코드와 맨 아래의 두줄 코드의 차이가..

 

linq로 foreach로도 바꿔보았다

(e.XmlData["rcpt_infos"] as List<Dictionary<string,object>>).ForEach(item =>
{
    MovieInfo m = new MovieInfo();
    mi.Add(DataManager.GetModelData(m, item) as MovieInfo);
});

 

더 간단한가.

Posted by 동동(이재동)