6
먼저 IEqualityComparer for anonymous type을보고 거기에 대한 답변이 IEqualityComparer
이 아니고 Linq의 Distinct()
메서드와 함께 사용하려면 IComparer
이 필요하다는 명백한 이유 때문에 내 질문에 대한 대답이 없습니다. 내가 조작하고 DataTable
Annoymous Type에 대한 IEqualityComparer
var glext = m_dtGLExt.AsEnumerable();
var cflist =
(from c in glext
orderby c.Field<string>(m_strpcCCType),
c.Field<string>(m_strpcCC),
c.Field<string>(m_strpcCCDesc),
c.Field<string>(m_strpcCostItem)
select new
{
CCType = c.Field<string>(m_strpcCCType),
CC = c.Field<string>(m_strpcCC),
CCDesc = c.Field<string>(m_strpcCCDesc),
CostItem = c.Field<string>(m_strpcCostItem)
}).Distinct();
에서 레코드를 끌어 몇 가지 코드를 가지고 ...
문제점
를 너무 다른 답변을 확인하고 이러한 솔루션에 미달하지만, 대소 문자를 구별하는 고유 한 방법이 필요합니다. 나를 던지는 것은 익명의 타입을 사용하는 것입니다. 나는 구체적인 목적을 가지고 SomeClass
이 있다면 나는 분명히
public class SumObject
{
public string CCType { get; set; }
public string CC { get; set; }
public string CCDesc { get; set; }
public string CostItem { get; set; }
}
을 할 수있는 해결 방법 1
시도
나는이
List<SumObject> lso = new List<SumObject>()
{
new SumObject() { CCType = "1-OCC", CC = "300401", CCDesc = "Rooney", CostItem = "I477" },
new SumObject() { CCType = "1-OCC", CC = "300401", CCDesc = "Zidane", CostItem = "I677" },
new SumObject() { CCType = "1-OCC", CC = "300401", CCDesc = "Falcao", CostItem = "I470" },
};
var e = lso.Distinct(new SumObjectComparer()); // Great :]
곳
class SumObjectComparer : IEqualityComparer<SumObject>
{
public bool Equals(SumObject x, SumObject y)
{
if (Object.ReferenceEquals(x, y))
return true;
if (Object.ReferenceEquals(x, null) || Object.ReferenceEquals(y, null))
return false;
return x.CCType.CompareNoCase(y.CCType) == 0 &&
x.CC.CompareNoCase(y.CC) == 0 &&
x.CCDesc.CompareNoCase(y.CCDesc) == 0 &&
x.CostItem.CompareNoCase(y.CostItem) == 0;
}
public int GetHashCode(SumObject o)
{
if (Object.ReferenceEquals(o, null))
return 0;
int hashCCType = String.IsNullOrEmpty(o.CCType) ?
0 : o.CCType.ToLower().GetHashCode();
int hashCC = String.IsNullOrEmpty(o.CC) ?
0 : o.CC.ToLower().GetHashCode();
int hashCCDesc = String.IsNullOrEmpty(o.CCDesc) ?
0 : o.CCDesc.ToLower().GetHashCode();
int hashCostItem = String.IsNullOrEmpty(o.CostItem) ?
0 : o.CostItem.ToLower().GetHashCode();
return hashCCType^hashCC^hashCCDesc^hashCostItem;
}
}
0,123 할 분명히 수
그러나 위의 Linq 쿼리에서 익명 형식을 사용하면 문제가 발생합니다. 이 또 다른 솔루션을 시도하기 위해
해결이 시도
(나는 다른 곳에서 같은 문제를 가지고 있기 때문에) 내가
public class GenericEqualityComparer<T> : IEqualityComparer<T>
{
Func<T, T, bool> compareFunction;
Func<T, int> hashFunction;
public GenericEqualityComparer(Func<T, T, bool> compareFunction, Func<T, int> hashFunction)
{
this.compareFunction = compareFunction;
this.hashFunction = hashFunction;
}
public bool Equals(T x, T y) { return compareFunction(x, y); }
public int GetHashCode(T obj) { return hashFunction(obj); }
}
내가 할 시도 할 수있는 다음과 같은 일반적인 비교 자 클래스를 생성
var comparer = new GenericEqualityComparer<dynamic>(
(x, y) => { /* My equality stuff */ },
o => { /* My hash stuff */ });
그러나이 값은 IEnumerable<dynamic>
으로 반환됩니다. 다음번의 쿼리에서 이 실패하지 않도록 cflist
을 사용할 예정입니다. 질문
var cf =
(from o in cflist
join od in glext
on new { o.CCType, o.CC, o.CCDesc, o.CostItem } equals new
{
CCType = od.Field<string>(m_strpcCCType),
CC = od.Field<string>(m_strpcCC),
CCDesc = od.Field<string>(m_strpcCCDesc),
CostItem = od.Field<string>(m_strpcCostItem)
}
into c
select new { ... }
난에이 코드를 많이 사용으로 인해
IEnumerable<T>
s의 추한 캐스팅에 들어갈 싶지 않아
...
는 방법은 내가 할 수 있는가 내 익명 유형에 대해 IEquailityComparer
을 만드시겠습니까?
감사합니다.
익명'select new' 개체를'select new SumObject' 개체로 바꾼 경우 첫 번째 해결책이 효과가있었습니다. 익명 객체를 사용하여 큰 문제는 무엇입니까? 이미 이름이 지정된 클래스를 만들었습니까? – dasblinkenlight
나는 그럴 수없고 그럴 수 없다. 내가 할 수 있으면 쉬울 것입니다. 또 다른 몇 가지 장소가 어디에 이러한 일반적인 작업 linq 선택 쿼리 및 익명 형식으로 작업을 좀 더 일반적인 솔루션을 싶습니다 ... – MoonKnight
그것은 느려질 것입니다,하지만 당신은 IEqualityComparer