Мне нужно реализовать изменяемый полигон , который ведет себя как структура, что он копируется по значению и изменения в копии не имеют побочных эффектов для оригинала.
Рассмотрим мою попытку при написании struct
для такого типа:
public unsafe struct Polygon : IEnumerable<System.Drawing.PointF>
{
private int points;
private fixed float xPoints[64];
private fixed float yPoints[64];
public PointF this[int i]
{
get => new PointF(xPoints[i], yPoints[i]);
set
{
xPoints[i] = value.X;
yPoints[i] = value.Y;
}
}
public IEnumerator<PointF> GetEnumerator()
{
return new PolygonEnumerator(ref this);
}
}
У меня есть требование, что Polygon
должен быть скопирован по значению, так что это struct
.
( Обоснование : Изменение копии не должно иметь побочных эффектов для оригинала. )
Я также хотел бы реализовать IEnumerable<PointF>
.
( Обоснование: Возможность писать for (PointF p in poly)
)
Насколько мне известно, C# не позволяет вам переопределить поведение копирования / назначения для типов значений. Если это возможно , то есть "низко висящий фрукт", который ответил бы на мой вопрос.
Мой подход к реализации поведения копирования по значению Polygon
заключается в использовании unsafe
и исправлены массивы, позволяющие многоугольнику хранить до 64 точек в самой структуре, что предотвращает косвенное изменение многоугольника через его копии.
Я сталкиваюсь с проблемой, когда я go реализую PolygonEnumerator : IEnumerator<PointF>
хотя.
Другое требование ( желаемое за действительное ) состоит в том, что перечислитель вернет PointF
значения, которые соответствуют фиксированным массивам Polygon
, даже если эти точки были изменены во время итерации.
( Обоснование: перебор массивов работает следующим образом, поэтому этот многоугольник должен вести себя в соответствии с ожиданиями пользователя. )
public class PolygonEnumerator : IEnumerator<PointF>
{
private int position = -1;
private ??? poly;
public PolygonEnumerator(ref Polygon p)
{
// I know I need the ref keyword to ensure that the Polygon
// passed into the constructor is not a copy
// However, the class can't have a struct reference as a field
poly = ???;
}
public PointF Current => poly[position];
// the rest of the IEnumerator implementation seems straightforward to me
}
Что можно сделать для реализации класс PolygonEnumerator
в соответствии с моими требованиями?
Мне кажется, что я не могу сохранить ссылку на исходный многоугольник, поэтому я должен сделать копию его точек. к самому счетчику; Но это означает, что счетчик не сможет увидеть изменения в исходном многоугольнике!
Я полностью согласен с ответом "Это невозможно".
Возможно, я вырыл яму для себя здесь, хотя отсутствует полезная языковая функция или традиционное решение исходной проблемы.