динамично украшающие объекты в c#

действительно ли возможно легко и динамично украсить объект?

например, позволяет, говорят, что у меня есть a List<PointF>. этот список является на самом деле графиком синусоидальной функции. Я хотел бы пройти эти точки и добавить флаг к каждому PointF того, является ли это пиком или нет.

но я не хочу создавать новый расширенный SpecialPointF или что бы то ни было, который имеет булево свойство.

судите меня все, что Вы хотите для того, чтобы быть ленивыми, но лень - то, как потрясающие идеи рождаются (также плохие идеи)

Править: Я приму решения для упаковки, а также любой интересный взлом, который можно придумать. нет ничего действительно мешать мне произойти. Я просто хочу знать, существует ли больше интересного способа.

10
задан Oren Mazor 29 April 2010 в 17:02
поделиться

4 ответа

Если есть способ вычислить это для каждой точки, вам не нужно добавлять к нему флаг, вы можете использовать метод extension без необходимости его расширения.

Что-то вроде PointF.isPeak ();

Это работает примерно так:

public static class Extensions
{
    public static bool isPeak (this PointF p)
    {
        do crazy math...

        return result;
    }
}

И вуаля, у вас есть расчет в вашем классе PointF.

Между прочим, публичный статический класс должен находиться во внешней области видимости и не может быть вложенным.

4
ответ дан 3 December 2019 в 23:12
поделиться

Это могло сделать это с помощью нового ключевого слова 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;
   }
}
3
ответ дан 3 December 2019 в 23:12
поделиться

Нет, нет способа сделать (конкретно) то, о чем вы просите.

Предполагая, что вы используете C # 3.0+, вы можете использовать для этого анонимные типы, предполагая, что вы не хотите раскрывать информацию за пределами вашей функции.

var decoratedList = sourceList.Select(pt => new 
                    { 
                        IsPeak = GetIsPeak(pt), 
                        Point = pt 
                    }).ToList();

Это даст вам новый объект List . Это вполне может не решить вашу проблему, поскольку вы не можете расширить это за пределы одного вызова функции, и вы создаете новый список, а не изменяете существующий, но, надеюсь, это поможет.

5
ответ дан 3 December 2019 в 23:12
поделиться

Нет, это невозможно.

Самый близкий будет просто создать

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, реализованы в библиотеках классов). Однако это по-прежнему означает, что вам нужно изменить подписи в тех местах, где вы используете тип (что, вероятно, не то, что вы хотите делать при поиске декоратора).

2
ответ дан 3 December 2019 в 23:12
поделиться
Другие вопросы по тегам:

Похожие вопросы: