가령 우리 에 게 클래스 가 있다 면:Productpublic class Product{ public string Id { get; set; } public string Name { get; set; }}주 함 수 는 다음 과 같 습 니 다:static void Main(){ List products = new List() { new Product(){ Id="1", Name="n1"}, new Product(){ Id="1", Name="n2"}, new Product(){ Id="2", Name="n1"}, new Product(){ Id="2", Name="n2"}, }; var distinctProduct = products.Distinct(); Console.ReadLine();}distinct 제품 의 결 과 를 볼 수 있 습 니 다Distinct 는 기본적으로 제품 대상 의 인용 을 비교 하기 때문에 4 개의 데 이 터 를 되 돌려 줍 니 다.그렇다면 Id 의 유일한 제품 으로 돌아 가 고 싶다 면 어떻게 해 야 할 까? Distinct 방법 은 또 다른 재 부팅 방법 이 있 습 니 다.//지정 한 System.collections.Generic.IEquality Comparer를 사용 하여 값 을 비교//반환 시퀀스 의 비 중복 요 소 를 사용 합 니 다. public static IEnumerable Distinct(this IEnumerable source, IEqualityComparer comparer);이 리 셋 은 IEquality Comparer 의 인 자 를 받 습 니 다.Id 로 선별 하려 면 새 클래스 ProductIdComparer 내용 은 다음 과 같 습 니 다:Public class ProductIdComparer:IEquality Comparer{ public bool Equals(Product x, Product y) { if (x == null) return y == null; return x.Id == y.Id; } public int GetHashCode(Product obj) { if (obj == null) return 0; return obj.Id.GetHashCode(); }}사용 할 때 var distinctProduct=products.Distinct(new ProductIdComparer())만 필요 합 니 다.결 과 는 다음 과 같다.분명 합 니 다.ProductNameComparer 를 하나 더 추가 해 야 합 니 다.그러면 범 형 류 를 사용 할 수 있 습 니까?새 클래스 PropertyComparer계승 IEquality Comparer내용 은 다음 과 같 습 니 다:public class PropertyComparer:IEquality Comparer{ private PropertyInfo _PropertyInfo; /// /// propertyName 을 통 해 PropertyInfo 대상 가 져 오기 /// /// public PropertyComparer(string propertyName) { _PropertyInfo = typeof(T).GetProperty(propertyName, BindingFlags.GetProperty | BindingFlags.Instance | BindingFlags.Public); if (_PropertyInfo == null) { throw new ArgumentException(string.Format("{0} is not a property of type {1}.", propertyName, typeof(T))); } } #region IEqualityComparer Members public bool Equals(T x, T y) { object xValue = _PropertyInfo.GetValue(x, null); object yValue = _PropertyInfo.GetValue(y, null); if (xValue == null) return yValue == null; return xValue.Equals(yValue); } public int GetHashCode(T obj) { object propertyValue = _PropertyInfo.GetValue(obj, null); if (propertyValue == null) return 0; else return propertyValue.GetHashCode(); } #endregion}은 주로 재 작성 한 Equals 와 GetHashCode 가 속성의 값 을 사용 하여 비교 합 니 다.사용 할 때://var distinctProduct=products.Distinct(new Property Comparer("Id")만 필요 합 니 다.var distinctProduct = products.Distinct(new PropertyComparer("Name"));결 과 는 다음 과 같다.위의 논리 에 따 르 면 이런 종 류 는 복잡 하지 않 을 것 이다.세심 한 학생 들 은 Property Equality 가 반 사 를 대량으로 사용 한 것 을 발견 할 수 있다.속성의 값 을 가 져 올 때마다 호출PropertyInfo.GetValue(x, null);선별 할 기록 이 많다 면 성능 에 영향 을 미 칠 수 밖 에 없다.성능 을 향상 시 키 기 위해 서 는 표현 식 트 리 를 사용 하여 반사 호출 을 위탁 호출 로 변경 할 수 있 습 니 다.구체 적 인 코드 는 다음 과 같 습 니 다:Public class FastProperty Comparer:IEquality Comparer{ private Func getPropertyValueFunc = null; /// /// propertyName 을 통 해 PropertyInfo 대상 가 져 오기 /// /// public FastPropertyComparer(string propertyName) { PropertyInfo _PropertyInfo = typeof(T).GetProperty(propertyName, BindingFlags.GetProperty | BindingFlags.Instance | BindingFlags.Public); if (_PropertyInfo == null) { throw new ArgumentException(string.Format("{0} is not a property of type {1}.", propertyName, typeof(T))); } ParameterExpression expPara = Expression.Parameter(typeof(T), "obj"); MemberExpression me = Expression.Property(expPara, _PropertyInfo); getPropertyValueFunc = Expression.Lambda>(me, expPara).Compile(); } #region IEqualityComparer Members public bool Equals(T x, T y) { object xValue = getPropertyValueFunc(x); object yValue = getPropertyValueFunc(y); if (xValue == null) return yValue == null; return xValue.Equals(yValue); } public int GetHashCode(T obj) { object propertyValue = getPropertyValueFunc(obj); if (propertyValue == null) return 0; else return propertyValue.GetHashCode(); } #endregion}현재 가 져 온 값 은 getProperty Value Func(obj)만 있 으 면 됩 니 다.사용 시:var distinctProduct=products.Distinct(new FastProperty Comparer("Id").ToList();
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다: