#c# #class #charts #delegates #wrapper
#c# #класс #Диаграммы #делегаты #оболочка
Вопрос:
Всем привет.Я разрабатываю библиотеку построения графиков с использованием Windows form c #, и я хотел бы спросить, как вы добавляете мои собственные методы к таким классам, как chart и series, независимо, не прерывая связь между ними?
Не беспокойтесь о веревке, это просто то, что я считал физическим для представления связи между диаграммой и серией, поскольку серия находится под диаграммой.
Я пытался использовать наследование и добавлять новые методы, но потом понял, что это не сработает, потому что при замене диаграммы, например, общедоступным классом Mychart : Chart , Mychart не будет взаимодействовать с chart.Series., как вы можете видеть из рисунка, объект, унаследованный от Chart , не имеет связи с Series ( т. Е. Нет связи между ними) , это упрощенная версия огромной проблемы, с которой я столкнулся в своем проекте. Я очень ценю любую помощь или попытку.
Чтобы уточнить, что я подразумеваю под отсутствием связи:
this.chart1 = new System.Windows.Forms.DataVisualization.Charting.Chart();
вы можете видеть, что chart1 был сгенерирован классом диаграмм, верно?
Хорошо, теперь продолжайте и замените chart на Mychart (с новыми методами)
this.chart2 = new System.Windows.Forms.DataVisualization.Charting.Mychart();
Но проблема возникает, когда вы пытаетесь сгенерировать ряды из Mychart.
System.Windows.Forms.DataVisualization.Charting.Series series2 = new System.Windows.Forms.DataVisualization.Charting.Series();
вы не могли бы снова выполнить наследование для series, потому что теперь, как вы можете видеть, Series находится под Chart, а не под Mychart, они вообще не связаны
System.Windows.Forms.DataVisualization.Mychart.NewSeries series2 = new System.Windows.Forms.DataVisualization.Mychart.NewSeries();
Новая серия вообще не существует <- в последнем коде я намеренно ошибся, чтобы показать вам, что не так с наследованием.
в конце концов, именно так я мог бы вызвать свою функцию, чтобы вы знали, почему соединение (rope) чрезвычайно важно .
private delegate int PlotXYDelegate(double x, double y); // define a function pointer
private void PlotXYAppend(Chart chart, Series dataSeries, double x, double y)
{
chart.Invoke(new PlotXYDelegate(dataSeries.Points.AddXY), new Object[] { x, y });
}
выше определена функция, которая принимает диаграмму, ряд, и я каждый раз передаю пару точек.
Комментарии:
1. Очень неясно, о чем вы спрашиваете. Ваша диаграмма хороша, но это не UML или любая другая известная мне нотация, и она не совсем проясняет вашу систему или проблемы. Попробуйте представить некоторые базовые фрагменты вашего кода и описать, чего вы хотите достичь.
2. Я только что прояснил вопрос, надеюсь, это может сделать его более очевидным. Этот вопрос более специфичен для пользователя c sharp win form
3. Запрещено ли добавлять методы непосредственно к диаграмме / ряду? Я не совсем понимаю концепцию «веревки». Что это такое на самом деле? Какой-то другой класс или просто смоделированное отношение между диаграммой и рядом (по звучанию, скорее всего, композиция)?
4. поскольку Series — это класс под диаграммой, вот почему я сказал, что у них есть соединение. Если вы продолжите и создадите новый класс, наследуемый от Chart, Mynewchart.series будет отличаться от chart.series. нет веревки … Rope — это просто то, что я придумал, чтобы упростить визуализацию.
5. Если вы создаете подкласс диаграммы, то он сможет использовать исходные ряды, которые определены внутри его родительского класса.
Ответ №1:
О НАСЛЕДОВАНИИ :
Вы используете класс Chart.
У него есть диаграмма. Свойство серии типа SeriesCollection.
Эта коллекция имеет метод Add, который принимает экземпляры серии. Но это не означает, что он будет принимать только экземпляры Series — он также будет принимать все, что является производным от класса Series.
Итак, например, вы создали своих собственных наследников диаграммы и ряда с помощью пользовательских методов:
using System.Windows.Forms.DataVisualization.Charting;
...
public class MyChart: Chart
{
public void MyChartMethod() { }
}
public class MySeries : Series
{
public MySeries(String name) : base(name)
{
}
public void MySeriesMethod() { }
}
Затем вы можете использовать их так же, как вы используете классические классы диаграмм и рядов взаимозаменяемо:
// Classic chart
Chart chart = new Chart();
chart.Series.Add(new Series("Classic series instance for Chart"));
chart.Series.Add(new MySeries("My series instance for Chart"));
this.Controls.Add(chart);
// MyChart
MyChart myChart = new MyChart();
chart.Series.Add(new Series("Classic series instance for MyChart"));
chart.Series.Add(new MySeries("My series instance for MyChart"));
this.Controls.Add(myChart );
...
myChart.MyChartMethod()
Единственная проблема, с которой вы можете столкнуться, заключается в том, что SeriesCollection хранит свои серии в виде ссылок на серии, поэтому в ваших методах вам придется использовать серию, которую вы используете:
public class MyChart: Chart
{
public void MyMethod()
{
MySeries mySeries = (MySeries)this.Series[0];
mySeries.MySeriesMethod();
}
}
Это не лучшее решение и потенциально может вызвать некоторые проблемы, если вы когда-нибудь решите смешать свои MySeries и оригинальные серии.
ОБ ОБЕРТКАХ :
Оболочки не означают наследования. Они используются, когда наследование не является опцией —http://en.wikipedia.org/wiki/Decorator_pattern. Обычно это что-то вроде:
public class Original
{
public void DoOriginal() { }
}
public class OriginalWrapper
{
private Original original;
public OriginalWrapper(Original original)
{
this.original = original;
}
public void DoOriginal() { original.DoOriginal();}
public void DoOriginalWrapper() { }
}
OriginalWrapper сможет делать все, что может оригинал новая функция DoOriginalWrapper(). Но он не наследуется от оригинала, поэтому вы не сможете использовать вместо исходных экземпляров:
public class ConsumerOfOriginal
{
public void ConsumeOriginal(Original original);
}
Original original = new Original();
OriginalWrapper originalWrapper = new OriginalWrapper(original);
Consumer consumer = new ConsumerOfOriginal();
consumer.ConsumeOriginal(original); // Compiles and works
consumer.ConsumeOriginal(originalWrapper); // Fails to compile
Чтобы преодолеть эту проблему, вам придется либо развернуть упакованный экземпляр, либо использовать интерфейсы в качестве параметров ваших методов.
РЕШЕНИЕ ВАШЕЙ ПРОБЛЕМЫ :
Я не знаю ваших точных сценариев, поэтому я не могу рекомендовать вам наследование композиции (перенос), но я надеюсь, что мой пост прояснил для вас хотя бы некоторые вещи.
Постскриптум: я бы рекомендовал вам прочитать:
http://www.codeproject.com/Articles/22769/Introduction-to-Object-Oriented-Programming-Concep
http://www.codeproject.com/Articles/618/OOP-and-UML
Они могут быть немного слишком сложными и содержать много информации, не имеющей значения на данный момент, но в конце они, по крайней мере, обрисуют и покажут многие концепции, полезные в программировании и проектировании ООП. Удачи.