в качестве другого примера, рассмотрим класс автомобилей, это будет хорошим использованием композиции, автомобиль будет иметь «двигатель», коробку передач, шины, сиденья и т. д. Он не будет распространять ни один из этих классов.
Можно использовать Счетный. Метод SequenceEqual .
using System;
using System.Linq;
...
var a1 = new int[] { 1, 2, 3};
var a2 = new int[] { 1, 2, 3};
var a3 = new int[] { 1, 2, 4};
var x = a1.SequenceEqual(a2); // true
var y = a1.SequenceEqual(a3); // false
, Если Вы не можете использовать.NET 3.5 по некоторым причинам, Ваш метод в порядке.
Compiler\run-разовая среда оптимизирует Ваш цикл, таким образом, Вы не должны будете волноваться о производительности.
Извините, при поиске управляемого способа, которым Вы уже делаете его правильно и к моему знанию существует не создано в методе в BCL для того, чтобы сделать это.
необходимо добавить некоторые начальные пустые проверки и затем просто снова использовать его как будто это где в BCL.
Если Вы не настроены против выполнения его, можно импортировать блок J# "vjslib.dll" и использовать Arrays.equals (байт [], байт []) метод ...
не обвиняют меня, если кто-то смеется над Вами хотя...
<час>РЕДАКТИРОВАНИЕ: Поскольку, что мало это стоит, я использовал Отражатель для разборки кода для этого, и здесь - то, на что это похоже:
public static bool equals(sbyte[] a1, sbyte[] a2)
{
if (a1 == a2)
{
return true;
}
if ((a1 != null) && (a2 != null))
{
if (a1.Length != a2.Length)
{
return false;
}
for (int i = 0; i < a1.Length; i++)
{
if (a1[i] != a2[i])
{
return false;
}
}
return true;
}
return false;
}
Я использовал бы небезопасный код и работал бы for
цикл, сравнивающий указатели Int32.
, Возможно, необходимо также полагать, что проверка массивов является непустой.
.NET 3.5 и новее имеют новый открытый тип, System.Data.Linq.Binary
, который инкапсулирует байт []
. Он реализует IEquatable
, который (в действительности) сравнивает два байтовых массива. Обратите внимание, что System.Data.Linq.Binary
также имеет оператор неявного преобразования из байта []
.
Документация MSDN: System.Data.Linq.Binary
Отражатель декомпиляции метода Equals:
private bool EqualsTo(Binary binary)
{
if (this != binary)
{
if (binary == null)
{
return false;
}
if (this.bytes.Length != binary.bytes.Length)
{
return false;
}
if (this.hashCode != binary.hashCode)
{
return false;
}
int index = 0;
int length = this.bytes.Length;
while (index < length)
{
if (this.bytes[index] != binary.bytes[index])
{
return false;
}
index++;
}
}
return true;
}
Интересный поворот состоит в том, что они переходят к байтовому циклу сравнения, только если хэши двух двоичных объектов совпадают. Это, однако, происходит за счет вычисления хэша в конструкторе двоичных
объектов (путем обхода массива с для цикла
:-)).
Я думал о методах ускорения передачи блоков, встроенных во многие видеокарты. Но тогда вам придется копировать все данные побайтно, так что это не поможет вам, если вы не хотите реализовывать целую часть своей логики в неуправляемом и аппаратно-зависимом коде ...
Другой способ оптимизации, аналогичный подходу, показанному выше, - это хранить как можно больше ваших данных в длинном [], а не в байтовом [] с самого начала, например, если вы читаете их последовательно из двоичного файла, или, если вы используете файл с отображением в память, считывайте данные как длинные [] или одиночные длинные значения. Тогда вашему циклу сравнения потребуется только 1/8 от числа итераций, которые он должен был бы сделать для байта [], содержащего такое же количество данных. Это вопрос того, когда и как часто вам нужно сравнивать, а когда и как часто вам нужно обращаться к данным побайтно, например, чтобы использовать их в вызове API в качестве параметра в методе, который ожидает байт []. В конце концов, вы можете сказать только, действительно ли знаете сценарий использования ...
Если вы посмотрите, как .NET выполняет string.Equals, вы увидите, что он использует закрытый метод EqualsHelper, который имеет «небезопасную» реализацию указателя. .NET Reflector - ваш друг, чтобы увидеть, как все делается внутри.
Его можно использовать в качестве шаблона для сравнения байтовых массивов, реализацию которого я реализовал в сообщении в блоге Быстрое сравнение байтовых массивов в C # . Я также провел несколько элементарных тестов, чтобы увидеть, когда безопасная реализация быстрее небезопасной.
Тем не менее, если вам действительно не нужна убийственная производительность, я бы пошел на простое сравнение цикла fr.
Для сравнения коротких байтовых массивов следующий интересный прием:
if(myByteArray1.Length != myByteArray2.Length) return false;
if(myByteArray1.Length == 8)
return BitConverter.ToInt64(myByteArray1, 0) == BitConverter.ToInt64(myByteArray2, 0);
else if(myByteArray.Length == 4)
return BitConverter.ToInt32(myByteArray2, 0) == BitConverter.ToInt32(myByteArray2, 0);
Тогда я бы, вероятно, выпал на решение, указанное в вопросе.
Было бы интересно сделать анализ производительности этого кода.
P / Invoke Powers activate!
[DllImport("msvcrt.dll", CallingConvention=CallingConvention.Cdecl)]
static extern int memcmp(byte[] b1, byte[] b2, long count);
static bool ByteArrayCompare(byte[] b1, byte[] b2)
{
// Validate buffers are the same length.
// This also ensures that the count does not exceed the length of either buffer.
return b1.Length == b2.Length && memcmp(b1, b2, b1.Length) == 0;
}