C #에서 배열 비교
두 배열을 서로 비교하려고합니다. 이 코드를 시도하고 다음 오류가 발생했습니다.
static bool ArraysEqual(Array a1, Array a2)
{
if (a1 == a2)
return true;
if (a1 == null || a2 == null)
return false;
if (a1.Length != a2.Length)
return false;
IList list1 = a1, list2 = a2; //error CS0305: Using the generic type 'System.Collections.Generic.IList<T>' requires '1' type arguments
for (int i = 0; i < a1.Length; i++)
{
if (!Object.Equals(list1[i], list2[i])) //error CS0021: Cannot apply indexing with [] to an expression of type 'IList'(x2)
return false;
}
return true;
}
왜 그 오류가 발생합니까? 저 기술 솔루션을 찾아서 잘 작동하지만 각 유형에 대해 여러 번 복사 / 붙여 넣기해야합니다.
static bool ArraysEqual(byte[] a1, byte[] a2)
{
if (a1 == a2)
return true;
if (a1 == null || a2 == null)
return false;
if (a1.Length != a2.Length)
return false;
for (int i = 0; i < a1.Length; i++)
{
if (a1[i] != a2[i])
return false;
}
return true;
}
LINQ를 사용할 수 있고 성능에 너무 신경 쓰지 않는다면 가장 쉬운 방법은 다음과 같습니다.
var arraysAreEqual = Enumerable.SequenceEqual(a1, a2);
실제로 메서드가 실제로 수행 하는 작업 을 Reflector 또는 ILSpy로 확인하는 SequenceEqual
것이 좋습니다. 어쨌든 배열 값의 특수한 경우에 최적화 할 수 있기 때문입니다!
"왜 그 오류가 발생합니까?" -아마도 using System.Collections;
파일 맨 위에 " using System.Collections.Generic;
"이 (가) 없을 것입니다.- " " 만 -그러나 제네릭이 아마도 더 안전 할 것입니다-아래를 참조하십시오.
static bool ArraysEqual<T>(T[] a1, T[] a2)
{
if (ReferenceEquals(a1,a2))
return true;
if (a1 == null || a2 == null)
return false;
if (a1.Length != a2.Length)
return false;
EqualityComparer<T> comparer = EqualityComparer<T>.Default;
for (int i = 0; i < a1.Length; i++)
{
if (!comparer.Equals(a1[i], a2[i])) return false;
}
return true;
}
For .NET 4.0 and higher you can compare elements in array or tuples via using StructuralComparisons type:
object[] a1 = { "string", 123, true };
object[] a2 = { "string", 123, true };
Console.WriteLine (a1 == a2); // False (because arrays is reference types)
Console.WriteLine (a1.Equals (a2)); // False (because arrays is reference types)
IStructuralEquatable se1 = a1;
//Next returns True
Console.WriteLine (se1.Equals (a2, StructuralComparisons.StructuralEqualityComparer));
Recommending SequenceEqual is ok, but thinking that it may ever be faster than usual for(;;) loop is too naive.
Here is the reflected code:
public static bool SequenceEqual<TSource>(this IEnumerable<TSource> first,
IEnumerable<TSource> second, IEqualityComparer<TSource> comparer)
{
if (comparer == null)
{
comparer = EqualityComparer<TSource>.Default;
}
if (first == null)
{
throw Error.ArgumentNull("first");
}
if (second == null)
{
throw Error.ArgumentNull("second");
}
using (IEnumerator<TSource> enumerator = first.GetEnumerator())
using (IEnumerator<TSource> enumerator2 = second.GetEnumerator())
{
while (enumerator.MoveNext())
{
if (!enumerator2.MoveNext() || !comparer.Equals(enumerator.Current, enumerator2.Current))
{
return false;
}
}
if (enumerator2.MoveNext())
{
return false;
}
}
return true;
}
As you can see it uses 2 enumerators and fires numerous method calls which seriously slow everything down. Also it doesn't check length at all, so in bad cases it can be ridiculously slower.
Compare moving two iterators with beautiful
if (a1[i] != a2[i])
and you will know what I mean about performance.
It can be used in cases where performance is really not so critical, maybe in unit test code, or in cases of some short list in rarely called methods.
SequenceEqual can be faster. Namely in the case where almost all of the time, both arrays have indeed the same length and are not the same object.
It's still not the same functionality as the OP's function, as it won't silently compare null values.
I know this is an old topic, but I think it is still relevant, and would like to share an implementation of an array comparison method which I feel strikes the right balance between performance and elegance.
static bool CollectionEquals<T>(ICollection<T> a, ICollection<T> b, IEqualityComparer<T> comparer = null)
{
return ReferenceEquals(a, b) || a != null && b != null && a.Count == b.Count && a.SequenceEqual(b, comparer);
}
The idea here is to check for all of the early out conditions first, then fall back on SequenceEqual
. It also avoids doing extra branching and instead relies on boolean short-circuit to avoid unecessary execution. I also feel it looks clean and is easy to understand.
Also, by using ICollection
for the parameters, it will work with more than just arrays.
참고URL : https://stackoverflow.com/questions/713341/comparing-arrays-in-c-sharp
'Development Tip' 카테고리의 다른 글
루트 비밀번호를 null로 설정하는 방법 (0) | 2020.11.25 |
---|---|
데이터베이스 복원 중 mssql '5 (액세스가 거부되었습니다.)'오류 (0) | 2020.11.25 |
프로토 타입 array.last ()에 해당하는 jQuery (0) | 2020.11.25 |
Does this function have explicit return values on all control paths? (0) | 2020.11.25 |
개발자가 알아야 할 유용한 비트 연산자 코드 트릭은 무엇입니까? (0) | 2020.11.25 |