У меня есть интерфейс IRenderable
и класс, который управляет рендерингом всех экземпляров классов, реализующих интерфейс.
У меня есть много классов в моем коде, и я ожидаю, что другие создадут классы, реализующие тот же интерфейс.
Из-за характера рендеринга я хочу сказать что-то вроде «Рисовать экземпляры этого класса перед экземплярами этого класса».
Типичный подход состоит в том, чтобы каждый класс реализовывал DrawOrder
свойство, однако мне это не нравится, потому что классы не имеют определенного значения порядка прорисовки, имеет значение относительный порядок .Если бы я дал каждому классу свойство DrawOrder
, то любой, кто реализует интерфейс, должен был бы знать, каковы значения всех классов.Очевидно, что это невозможно, если многие люди смогут реализовать свой собственный класс.
Мне бы хотелось иметь возможность определять правила, которые говорят: «ClassA перед ClassB, ClassC перед ClassA», затем, когдавырабатывая порядок прорисовки / добавляя экземпляры, я мог бы вывести правильный порядок прорисовки.Другие, реализующие интерфейс, могут добавлять свои собственные правила, относящиеся к встроенным реализациям, и свои собственные дополнения.
РЕДАКТИРОВАТЬ: Я надеюсь, что какой-то класс управляет правилами иуправляет поддержанием порядка, как показано ниже:
class Renderer
{
private List<Rule> Rules;
private List<IRenderable> Renderables;
// Adds to list of rules
void EnforceBefore(Type FirstClass, Type SecondClass);
// Inserts items ensuring all rules are followed.
void Insert(IRenderable ClassInstance);
void RenderAll();
}
Затем классы могут добавлять правила соответствующим образом (или у меня может быть метод интерфейса, который их возвращает).
Ниже приведенбыстрый тест, который не работает
using System;
using System.Collections.Generic;
using System.Linq;
class Program
{
static void Main(string[] args)
{
List<string> MyList = new List<string> { "wherever", "second", "first", "third", "first", "third", "second" };
RuleBasedComparer<string> RuleComparer = new RuleBasedComparer<string>();
// I want to ensure all instances of "first" appear in the list before all instances of "second"
// and all instances of "second" appear in the list before all instances of "third".
// I don't care where "wherever" appears (or anything beyond the above rules)
RuleComparer.AddRule("first", "second");
RuleComparer.AddRule("second", "third");
MyList.Sort(RuleComparer);
foreach (var item in MyList)
Console.WriteLine(item);
Console.ReadKey();
}
}
public class RuleBasedComparer<T> : Comparer<T>
{
private class OrderRule
{
public readonly T Before;
public readonly T After;
public OrderRule(T before, T after)
{
Before = before;
After = after;
}
}
private List<OrderRule> _Rules = new List<OrderRule>();
public void AddRule(T before, T after)
{
_Rules.Add(new OrderRule(before, after));
}
public override int Compare(T x, T y)
{
// Find the applicable rule for this pair (if any)
var ApplicableRule = _Rules.Where(or => or.After.Equals(x) && or.Before.Equals(y) ||
or.After.Equals(y) && or.Before.Equals(x)).SingleOrDefault();
if (ApplicableRule != null)
{
// If there is a rule then if x should be before y then return -1, otherwise return 1
if (ApplicableRule.Before.Equals(x))
return -1;
else
return 1;
}
else
{
// If no rule exists then say they are equal
return 0;
}
}
}
TL; DR: как перейти от правил, которые говорят такие вещи, как "ClassA before ClassB", к определенному порядку экземпляров/classes.
Неоднозначности, вызванные отсутствием полных правил, не должны иметь значения, я просто хочу придерживаться существующих правил.