첨부 실행 코드는 나눔고딕코딩 폰트를 사용합니다.
유용한 소스 코드가 있으면 icodebroker@naver.com으로 보내주시면 감사합니다.
블로그 자료는 자유롭게 사용하세요.

■ 객체 리스트 특정 객체 속성 값의 집합 구하기 (속성 2개 이상 지정 가능)

----------------------------------------------------------------------------------------------------

using System;

using System.Collections.Generic;

using System.ComponentModel;

using System.Linq;

 

#region 객체 리스트 특정 객체 속성 값의 집합 구하기 - GetDistinctList(sourceList, propertyNameArray)

 

/// <summary>

/// 객체 리스트 특정 객체 속성 값의 집합 구하기

/// </summary>

/// <param name="sourceList">소스 리스트</param>

/// <param name="propertyNameArray">속성명 배열</param>

/// <returns>객체 리스트 특정 객체 속성 값의 집합</returns>

public List<object> GetDistinctList(List<object> sourceList, string[] propertyNameArray)

{

    if(sourceList == null || sourceList.Count == 0)

    {

        return null;

    }

 

    var result = sourceList.AsEnumerable().GroupBy(item =>

        new DistinctTuple<object>

        (

            from propertyName in propertyNameArray select item.GetType().GetProperty(propertyName).GetValue(item))

        );

 

    int propertyNameCount = propertyNameArray.Length;

 

    PropertyDescriptorCollection pdc = TypeDescriptor.GetProperties(sourceList[0]);

 

    DynamicClass dynamicClass = new DynamicClass(); // '동적 클래스 사용하기' 참조

 

    for(int i = 0; i < propertyNameCount; i++)

    {

        dynamicClass.AddProperty(propertyNameArray[i], pdc[propertyNameArray[i]].PropertyType);

    }

 

    dynamicClass.CreateType();

 

    List<object> targetList = new List<object>();

 

    foreach(var group in result)

    {

        dynamicClass.CreateInstance();

 

        for(int i = 0; i < propertyNameCount; i++)

        {

            dynamicClass.SetValue(i, group.Key.ValueArray[i]);

        }

 

        targetList.Add(dynamicClass.Instance);

    }

 

    return targetList;

}

 

#endregion

 

 

 

/// <summary>

/// 중복 제거 튜플

/// </summary>

/// <typeparam name="T">타입</typeparam>

public class DistinctTuple<T> : IEquatable<DistinctTuple<T>>

{

    //////////////////////////////////////////////////////////////////////////////////////////////////// Field

    ////////////////////////////////////////////////////////////////////////////////////////// Public

 

    #region Field

 

    /// <summary>

    /// 값 배열

    /// </summary>

    public readonly T[] ValueArray;

 

    #endregion

 

    //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor

    ////////////////////////////////////////////////////////////////////////////////////////// Public

 

    #region 생성자 - DistinctTuple(enumerable)

 

    /// <summary>

    /// 생성자

    /// </summary>

    /// <param name="enumerable">열거 가능형</param>

    public DistinctTuple(IEnumerable<T> enumerable)

    {

        ValueArray = enumerable.ToArray();

    }

 

    #endregion

 

    //////////////////////////////////////////////////////////////////////////////////////////////////// Method

    ////////////////////////////////////////////////////////////////////////////////////////// Public

 

    #region 동등 여부 조사하기 - Equals(sourceTuple)

 

    /// <summary>

    /// 동등 여부 조사하기

    /// </summary>

    /// <param name="sourceTuple">소스 Tuple</param>

    /// <returns>동등 여부</returns>

    public bool Equals(DistinctTuple<T> sourceTuple)

    {

        if(ReferenceEquals(this, sourceTuple))

        {

            return true;

        }

 

        if(sourceTuple == null)

        {

            return false;

        }

 

        int length = ValueArray.Length;

 

        if(length != sourceTuple.ValueArray.Length)

        {

            return false;

        }

 

        for(int i = 0; i < length; i++)

        {

            if(!Equals(ValueArray[i], sourceTuple.ValueArray[i]))

            {

                return false;

            }

        }

 

        return true;

    }

 

    #endregion

 

    #region 동등 여부 조사하기 - Equals(sourceObject)

 

    /// <summary>

    /// 동등 여부 조사하기

    /// </summary>

    /// <param name="sourceObject">소스 객체</param>

    /// <returns>동등 여부</returns>

    public override bool Equals(object sourceObject)

    {

        if(ReferenceEquals(this, sourceObject))

        {

            return false;

        }

 

        if(sourceObject == null)

        {

            return false;

        }

 

        return Equals(sourceObject as DistinctTuple<T>);

    }

 

    #endregion

 

    #region 해시 코드 구하기 - GetHashCode()

 

    /// <summary>

    /// 해시 코드 구하기

    /// </summary>

    /// <returns>해시 코드</returns>

    public override int GetHashCode()

    {

        int hashCode = 17;

 

        foreach(var value in ValueArray)

        {

            hashCode = hashCode * 37 + (!ReferenceEquals(value, null) ? value.GetHashCode() : 0);

        }

 

        return hashCode;

    }

 

    #endregion

}

----------------------------------------------------------------------------------------------------

Posted by 사용자 icodebroker
TAG

댓글을 달아 주세요