Мне жаль, что я не знаю, с какой конкретной проблемой вы сталкиваетесь или как ее решить [конечно, проверка ссылок на пространство имен и разрешение любых конфликтов с помощью методов с аналогичными именами - это начало], но я заметил одну или две странности .
Рассмотрим следующий пример решения,
using System.Linq;
namespace Sample.Extensions
{
public static class ByteExtensions
{
public static void RemoveHeader (this byte[] buffer, byte[] header)
{
// take first sequence of bytes, compare to header, if header
// is present, return only content
//
// NOTE: Take, SequenceEqual, and Skip are standard Linq extensions
if (buffer.Take (header.Length).SequenceEqual (header))
{
buffer = buffer.Skip (header.Length).ToArray ();
}
}
}
}
Это компилируется и запускается в VS2010RC. Чтобы продемонстрировать использование,
using Sample.Extensions;
namespace Sample
{
class Program
{
static void Main (string[] args)
{
byte[] buffer = new byte[] { 00, 01, 02 };
byte[] header = new byte[] { 00, 01 };
buffer.RemoveHeader (header);
// hm, so everything compiles and runs, but buffer == { 00, 01, 02 }
}
}
}
Таким образом, мы не получим компиляцию или время выполнения ошибка , но, очевидно, она не будет работать так, как задумано. Это связано с тем, что расширения должны по-прежнему соответствовать стандартной семантике метода, то есть параметры передаются по значению. Мы не можем изменить buffer
, чтобы он указывал на наш новый массив.
Мы можем решить эту проблему, переписав наш метод на обычную семантику функций,
public static byte[] RemoveHeaderFunction (this byte[] buffer, byte[] header)
{
byte[] stripped = null;
if (stripped.Take (header.Length).SequenceEqual (header))
{
stripped = stripped.Skip (header.Length).ToArray ();
}
else
{
stripped = buffer.ToArray ();
}
return stripped;
}
Теперь
using Sample.Extensions;
namespace Sample
{
class Program
{
static void Main (string[] args)
{
byte[] buffer = new byte[] { 00, 01, 02 };
byte[] header = new byte[] { 00, 01 };
// old way, buffer will still contain { 00, 01, 02 }
buffer.RemoveHeader (header);
// new way! as a function, we obtain new array of { 02 }
byte[] stripped = buffer.RemoveHeaderFunction (header);
}
}
}
К сожалению, массивы являются неизменяемыми типами значений [могут неправильно использовать эти термины]. Единственный способ изменить ваш «массив» на месте - это изменить контейнер на изменяемый ссылочный тип, например List<byte>
.
Если вы действительно заинтересованы в "передаче по ссылке", на месте, семантике побочных эффектов, то один из вариантов может быть следующим
using System.Linq;
namespace Sample.Extensions
{
public static class ListExtensions
{
public static void RemoveHeader<T> (this List<T> list, List<T> header)
{
if (list.Take (header.Count).SequenceEqual (header))
{
list.RemoveRange (0, header.Count);
}
}
}
}
Что касается использования,
static void Main (string[] args)
{
byte[] buffer = new byte[] { 00, 01, 02 };
byte[] header = new byte[] { 00, 01 };
List<byte> bufferList = buffer.ToList ();
// in-place side-effect header removal
bufferList.RemoveHeader (header.ToList ());
}
Под капотом List<T>
поддерживает массив типа T
. При определенных порогах это просто манипулирование базовым массивом и \ или создание новых массивов для нас.
Надеюсь, это поможет! :)