действительно ли возможно легко и динамично украсить объект?
например, позволяет, говорят, что у меня есть a List<PointF>
. этот список является на самом деле графиком синусоидальной функции. Я хотел бы пройти эти точки и добавить флаг к каждому PointF того, является ли это пиком или нет.
но я не хочу создавать новый расширенный SpecialPointF или что бы то ни было, который имеет булево свойство.
судите меня все, что Вы хотите для того, чтобы быть ленивыми, но лень - то, как потрясающие идеи рождаются (также плохие идеи)
Править: Я приму решения для упаковки, а также любой интересный взлом, который можно придумать. нет ничего действительно мешать мне произойти. Я просто хочу знать, существует ли больше интересного способа.
Если есть способ вычислить это для каждой точки, вам не нужно добавлять к нему флаг, вы можете использовать метод extension без необходимости его расширения.
Что-то вроде PointF.isPeak ();
Это работает примерно так:
public static class Extensions
{
public static bool isPeak (this PointF p)
{
do crazy math...
return result;
}
}
И вуаля, у вас есть расчет в вашем классе PointF.
Между прочим, публичный статический класс должен находиться во внешней области видимости и не может быть вложенным.
Это могло сделать это с помощью нового ключевого слова dynamic и конструкции ExpandoObject
в C # 4.0, но у меня нет личного опыта с этим. пока что. Насколько я понимаю, он был создан для легкого решения этой точной проблемы, поэтому вы можете сказать
dynamic something = new ExpandoObject();
something.Anything = "whatever you want";
Я верю , что можно динамически расширять существующие типы, но для этого может потребоваться создание нового подкласса, который победит вся цель упражнения.
Практически идентичное решение можно создать с помощью методов расширения. ExpandoObject
внутренне реализован как Словарь
, но он добавляет отличный собственный синтаксис.
class Program {
static void Main(string[] args)
{
PointF p = new PointF(0, 0);
p.SetFlag(true);
if (p.GetFlag())
Console.WriteLine("win");
}
}
public static class Extensions
{
private static Dictionary<PointF, bool> flags = new Dictionary<PointF, bool>();
public static bool GetFlag(this PointF key)
{
return flags[key];
//OR return flags.ContainsKey(key) ? flags[key] : false;
}
public static void SetFlag(this PointF key, bool val)
{
flags[key] = val;
}
}
Нет, нет способа сделать (конкретно) то, о чем вы просите.
Предполагая, что вы используете C # 3.0+, вы можете использовать для этого анонимные типы, предполагая, что вы не хотите раскрывать информацию за пределами вашей функции.
var decoratedList = sourceList.Select(pt => new
{
IsPeak = GetIsPeak(pt),
Point = pt
}).ToList();
Это даст вам новый объект List
. Это вполне может не решить вашу проблему, поскольку вы не можете расширить это за пределы одного вызова функции, и вы создаете новый список, а не изменяете существующий, но, надеюсь, это поможет.
Нет, это невозможно.
Самый близкий будет просто создать
var decorationData = new Dictionary <Object, bool>
, а затем сохранить в нем ваши значения. Нет необходимости расширять тип напрямую. Вы даже можете использовать метод расширения для доступа к сохраненным данным, которые будут выглядеть как прямое свойство объекта.
public static class PointFPeakExtensions
{
private static var decorationData = new Dictionary <PointF, bool>
public static bool IsPeak (this PointF point)
{
return decorationData[point];
}
public static void SetPeak (this PointF point, bool isPeak)
{
decorationData[point] = isPeak;
}
}
И добавив к вашему редактированию:
Вы также можете решить эту проблему с помощью универсального типа, который содержит только данные оформления и ссылочный тип (так же, как типы, допускающие значение NULL, реализованы в библиотеках классов). Однако это по-прежнему означает, что вам нужно изменить подписи в тех местах, где вы используете тип (что, вероятно, не то, что вы хотите делать при поиске декоратора).