473,395 Members | 1,631 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,395 software developers and data experts.

Derive Enum

Imagine you have a charting library that can draw lines, bars,
floating bars, bands, etc.
Lines and bars need only one input. Floating bars and bands need two
inputs. There are two approaches:

1) One enum with all 4 types (bars, band, etc). One chart class that
accepts up to 2 arrays of values. If the user choses a band but there
is only one input array throw an exception. If the user passes two
input arrays with different lengths throw an exception.

2) One enum with all 4 types. A class that accepts one array. Another
class that accepts two arrays or alternatively pair of values. We
still have to throw an exception if the "one array class" is chosen
but a band type is selected.

3) An enum for 1-input-charts (line,bar) and one for 2-input-charts. A
class that accepts only one input and one that accepts only two
inputs. The later class uses the later enum.

What approach is the best? If it's 3 then I would need something like
this:

interface IChart
{
ChartType Type { get; }
}

The problem is that ChartType is an enum and one cannot derive from
enums. How would that be solved?

Thanks

Apr 18 '07 #1
3 3017
On 18 Apr, 07:07, "hufaun...@yahoo.com" <hufaun...@yahoo.comwrote:
Imagine you have a charting library that can draw lines, bars,
floating bars, bands, etc.
Lines and bars need only one input. Floating bars and bands need two
inputs. There are two approaches:

1) One enum with all 4 types (bars, band, etc). One chart class that
accepts up to 2 arrays of values. If the user choses a band but there
is only one input array throw an exception. If the user passes two
input arrays with different lengths throw an exception.

2) One enum with all 4 types. A class that accepts one array. Another
class that accepts two arrays or alternatively pair of values. We
still have to throw an exception if the "one array class" is chosen
but a band type is selected.

3) An enum for 1-input-charts (line,bar) and one for 2-input-charts. A
class that accepts only one input and one that accepts only two
inputs. The later class uses the later enum.

What approach is the best? If it's 3 then I would need something like
this:

interface IChart
{
ChartType Type { get; }

}

The problem is that ChartType is an enum and one cannot derive from
enums. How would that be solved?

Thanks
I don't understand your last statement, why would you want to try and
derive from an enum?
I'd stick with one enum if you plan to have both types of charts
implement an interface.
I've attached a little example. It's not necessarily exactly what you
want but shows a few examples of different ways of doing it. In a
nutshell there's an interface for all chart types which just exposes
type and a draw method, then two types of chart one that needs two
sets of parameters and one that works with only one. These are created
by a factory class that has variously overloaded CreateChart methods.
Some of the bits are a redundant, I've just added them to show
different approaches, for example the parameter class has a validate
method, but the same validation is repeated in the factory.
There are plenty of other ways of doing it, you could have a base
Chart object that handles the basics and then derive specialised
charts from there for example.

Paste it over a new console app and it should run. If not, check for
line breaks.

using System;

namespace ConsoleApplication9
{
class Class1
{
[STAThread]
static void Main(string[] args)
{
IChart myFirstChart;
IChart mySecondChart;
IChart myThirdChart;

int[] series1 = new int[]{1,2,3,4,5,6,7,8,9,10};
int[] series2 = new int[]{11,12,13,14,15,16,17,18,19,20};
System.Collections.ArrayList param = new
System.Collections.ArrayList();

myFirstChart =
ChartFactory.CreateChart(ChartType.LineChart,serie s1);

param.Add(series1);
param.Add(series2);
mySecondChart =
ChartFactory.CreateChart(ChartType.BandsChart,para m);

ChartParameters paramObj = new ChartParameters(ChartType.BarChart,
series2, null);
myThirdChart = ChartFactory.CreateChart(paramObj);

myFirstChart.Draw();
mySecondChart.Draw();
myThirdChart.Draw();
Console.Read();
}
}
public enum ChartType
{
LineChart,
BarChart,
FloatingBarChart,
BandsChart
}
public interface IChart
{
ChartType TypeOfChart
{
get;
}
void Draw();
}
public class ChartFactory
{
public static IChart CreateChart(ChartType pType, params object[]
pParams)
{
//Comically this one will never be used because of
//public static IChart CreateChart(ChartType pType, int[] pSeries1,
int[] pSeries2) below
switch(pParams.Length)
{
case 1:
ChartFactory.CreateChart(pType,(int[])pParams[0]);
break;
case 2:
ChartFactory.CreateChart(pType,(int[])pParams[0],pParams[1]);
break;
default:
throw new Exception("Eeep!");
}
return null;
}
public static IChart CreateChart(ChartType pType,
System.Collections.ArrayList pData)
{
return ChartFactory.CreateChart(pType, (int[])pData[0],
(pData.Count==2 ? (int[])pData[1] : null));
}
public static IChart CreateChart(ChartType pType, int[] pSeries)
{
return ChartFactory.CreateChart(pType, pSeries, null);
}
public static IChart CreateChart(ChartParameters pParameters)
{
pParameters.Validate();
return
ChartFactory.CreateChart(pParameters.TypeOfChart,p Parameters.Series1,
pParameters.Series2);
}
public static IChart CreateChart(ChartType pType, int[] pSeries1,
int[] pSeries2)
{
switch(pType)
{
case ChartType.LineChart:
case ChartType.BarChart:
if (pSeries2 == null)
{
return new SingleArrayChart(pType, pSeries1);
}
else
{
throw new Exception("Expected one set of data");
}
case ChartType.FloatingBarChart:
case ChartType.BandsChart:
if (pSeries2 == null)
{
throw new Exception("Expected two sets of data");
}
else
{
return new DoubleArrayChart(pType, pSeries1, pSeries2);
}
default:
return null;
}
}
}
public class SingleArrayChart : IChart
{
private ChartType _chartType;
private int[] _data;
public SingleArrayChart(ChartType pType, int[] pData)
{
_chartType = pType;
_data = pData;
}
public ChartType TypeOfChart
{
get
{
return _chartType;
}
}
public void Draw()
{
Console.WriteLine("I am drawing a {0}",_chartType.ToString());
}
}
public class DoubleArrayChart : IChart
{
private ChartType _chartType;
private int[] _data1;
private int[] _data2;
public DoubleArrayChart(ChartType pType, int[] pData1, int[] pData2)
{
_chartType = pType;
_data1 = pData1;
_data2 = pData2;
if(_data1.Length != _data2.Length)
{
throw new Exception("Data arrays have differents lengths");
}
}
public ChartType TypeOfChart
{
get
{
return _chartType;
}
}
public void Draw()
{
Console.WriteLine("I am drawing a {0}",_chartType.ToString());
}
}
public class ChartParameters
{
// should all be properties
public int[] Series1;
public int[] Series2;
public ChartType TypeOfChart;

public ChartParameters(ChartType pType, int[] pSeries1, int[]
pSeries2)
{
Series1 = pSeries1;
Series2 = pSeries2;
TypeOfChart = pType;
}
public void Validate()
{
switch(TypeOfChart)
{
case ChartType.BarChart:
case ChartType.LineChart:
if (Series2 != null || Series1 == null)
{
throw new Exception("Expected one set of data");
}
break;
case ChartType.FloatingBarChart:
case ChartType.BandsChart:
if(Series2 == null || Series1 == null)
{
throw new Exception("Expected two sets of data");
}
if(Series2.Length != Series1.Length)
{
throw new Exception("Series data should be same length");
}
break;
}
}
}
}

Apr 18 '07 #2
On Apr 18, 5:29 am, DeveloperX <nntp...@operamail.comwrote:
On 18 Apr, 07:07, "hufaun...@yahoo.com" <hufaun...@yahoo.comwrote:


Imagine you have a charting library that can draw lines, bars,
floating bars, bands, etc.
Lines and bars need only one input. Floating bars and bands need two
inputs. There are two approaches:
1) One enum with all 4 types (bars, band, etc). One chart class that
accepts up to 2 arrays of values. If the user choses a band but there
is only one input array throw an exception. If the user passes two
input arrays with different lengths throw an exception.
2) One enum with all 4 types. A class that accepts one array. Another
class that accepts two arrays or alternatively pair of values. We
still have to throw an exception if the "one array class" is chosen
but a band type is selected.
3) An enum for 1-input-charts (line,bar) and one for 2-input-charts. A
class that accepts only one input and one that accepts only two
inputs. The later class uses the later enum.
What approach is the best? If it's 3 then I would need something like
this:
interface IChart
{
ChartType Type { get; }
}
The problem is that ChartType is an enum and one cannot derive from
enums. How would that be solved?
Thanks

I don't understand your last statement, why would you want to try and
derive from an enum?
I'd stick with one enum if you plan to have both types of charts
implement an interface.
I've attached a little example. It's not necessarily exactly what you
want but shows a few examples of different ways of doing it. In a
nutshell there's an interface for all chart types which just exposes
type and a draw method, then two types of chart one that needs two
sets of parameters and one that works with only one. These are created
by a factory class that has variously overloaded CreateChart methods.
Some of the bits are a redundant, I've just added them to show
different approaches, for example the parameter class has a validate
method, but the same validation is repeated in the factory.
There are plenty of other ways of doing it, you could have a base
Chart object that handles the basics and then derive specialised
charts from there for example.

Paste it over a new console app and it should run. If not, check for
line breaks.

using System;

namespace ConsoleApplication9
{
class Class1
{
[STAThread]
static void Main(string[] args)
{
IChart myFirstChart;
IChart mySecondChart;
IChart myThirdChart;

int[] series1 = new int[]{1,2,3,4,5,6,7,8,9,10};
int[] series2 = new int[]{11,12,13,14,15,16,17,18,19,20};
System.Collections.ArrayList param = new
System.Collections.ArrayList();

myFirstChart =
ChartFactory.CreateChart(ChartType.LineChart,serie s1);

param.Add(series1);
param.Add(series2);
mySecondChart =
ChartFactory.CreateChart(ChartType.BandsChart,para m);

ChartParameters paramObj = new ChartParameters(ChartType.BarChart,
series2, null);
myThirdChart = ChartFactory.CreateChart(paramObj);

myFirstChart.Draw();
mySecondChart.Draw();
myThirdChart.Draw();
Console.Read();
}
}
public enum ChartType
{
LineChart,
BarChart,
FloatingBarChart,
BandsChart
}
public interface IChart
{
ChartType TypeOfChart
{
get;
}
void Draw();
}
public class ChartFactory
{
public static IChart CreateChart(ChartType pType, params object[]
pParams)
{
//Comically this one will never be used because of
//public static IChart CreateChart(ChartType pType, int[] pSeries1,
int[] pSeries2) below
switch(pParams.Length)
{
case 1:
ChartFactory.CreateChart(pType,(int[])pParams[0]);
break;
case 2:
ChartFactory.CreateChart(pType,(int[])pParams[0],pParams[1]);
break;
default:
throw new Exception("Eeep!");
}
return null;
}
public static IChart CreateChart(ChartType pType,
System.Collections.ArrayList pData)
{
return ChartFactory.CreateChart(pType, (int[])pData[0],
(pData.Count==2 ? (int[])pData[1] : null));
}
public static IChart CreateChart(ChartType pType, int[] pSeries)
{
return ChartFactory.CreateChart(pType, pSeries, null);
}
public static IChart CreateChart(ChartParameters pParameters)
{
pParameters.Validate();
return
ChartFactory.CreateChart(pParameters.TypeOfChart,p Parameters.Series1,
pParameters.Series2);
}
public static IChart CreateChart(ChartType pType, int[] pSeries1,
int[] pSeries2)
{
switch(pType)
{
case ChartType.LineChart:
case ChartType.BarChart:
if (pSeries2 == null)
{
return new SingleArrayChart(pType, pSeries1);
}
else
{
throw new Exception("Expected one set of data");
}
case ChartType.FloatingBarChart:
case ChartType.BandsChart:
if (pSeries2 == null)
{
throw new Exception("Expected two sets of data");
}
else
{
return new DoubleArrayChart(pType, pSeries1, pSeries2);
}
default:
return null;
}
}
}
public class SingleArrayChart : IChart
{
private ChartType _chartType;
private int[] _data;
public SingleArrayChart(ChartType pType, int[] pData)
{
_chartType = pType;
_data = pData;
}
public ChartType TypeOfChart
{
get
{
return _chartType;
}
}
public void Draw()
{
Console.WriteLine("I am drawing a {0}",_chartType.ToString());
}
}
public class DoubleArrayChart : IChart
{
private ChartType _chartType;
private int[] _data1;
private int[] _data2;
public DoubleArrayChart(ChartType pType, int[] pData1, int[] pData2)
{
_chartType = pType;
_data1 = pData1;
_data2 = pData2;
if(_data1.Length != _data2.Length)
{
throw new Exception("Data arrays have differents lengths");
}
}
public ChartType TypeOfChart
{
get
{
return _chartType;
}
}
public void Draw()
{
Console.WriteLine("I am drawing a {0}",_chartType.ToString());
}
}
public class ChartParameters
{
// should all be properties
public int[] Series1;
public int[] Series2;
public ChartType TypeOfChart;

public ChartParameters(ChartType pType, int[] pSeries1, int[]
pSeries2)
{
Series1 = pSeries1;
Series2 = pSeries2;
TypeOfChart = pType;
}
public void Validate()
{
switch(TypeOfChart)
{
case ChartType.BarChart:
case ChartType.LineChart:
if (Series2 != null || Series1 == null)
{
throw new Exception("Expected one set of data");
}
break;
case ChartType.FloatingBarChart:
case ChartType.BandsChart:
if(Series2 == null || Series1 == null)
{
throw new Exception("Expected two sets of data");
}
if(Series2.Length != Series1.Length)
{
throw new Exception("Series data should be same length");
}
break;
}
}
}

}- Hide quoted text -

- Show quoted text -- Hide quoted text -

- Show quoted text -
Wow, thanks a lot for that reply.That leaves me with just one
question. What is a factory useful here? When you create a chart you
actually have to know what arguments (one or two) you have to supply.
If I already have that information I could the ctor of the appropriate
function directly. I'm sure there is a good reason. It's just that I
am not too familiar with that concept. Thanks again for the answer.

Apr 19 '07 #3
Wow, thanks a lot for that reply.That leaves me with just one
question. What is a factory useful here? When you create a chart you
actually have to know what arguments (one or two) you have to supply.
If I already have that information I could the ctor of the appropriate
function directly. I'm sure there is a good reason. It's just that I
am not too familiar with that concept. Thanks again for the answer.
It's just one approach really. As we're interested in getting an
IChart out, as opposed to a LineChart or a BarChart specifically, it
seemed sensible to create a factory which will validate your request
and return the appropriate IChart or raise the appropriate error.

One of the key points of using an interface is that you're saying "I
have a number of different classes, all of which should function in a
specific way". This means your code that uses the Chart library should
expect each chart to be able to draw itself for example. If you do
something like:

IChart myChart = new BarChart(...);

you're committing to using a BarChart in that bit of code. If you need
it to be configurable your applications will end up with methods that
return IChart references and do effectively what the Factory does. The
factory way means we're keeping everything in the same place which
makes it maintainable. As there's only one place that creates charts,
if you update that one place, all the applications that use the charts
will be updated.

I hope that made some sense :)

Apr 19 '07 #4

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

20
by: Glenn Venzke | last post by:
I'm writing a class with a method that will accept 1 of 3 items listed in an enum. Is it possible to pass the item name without the enum name in your calling statement? EXAMPLE: public enum...
21
by: Andreas Huber | last post by:
Hi there Spending half an hour searching through the archive I haven't found a rationale for the following behavior. using System; // note the missing Flags attribute enum Color {
31
by: Michael C | last post by:
If a class inherits from another class, say Form inherits from control, then I can assign the Form to a variable of type Control without needing an explicit conversion, eg Form1 f = new Form1();...
18
by: Visual Systems AB \(Martin Arvidsson\) | last post by:
Hi! I have created an enum list like this: enum myEnum : int { This = 2, That, NewVal = 10, LastItm
2
by: Dennis | last post by:
I have an enum as follows: Public Enum myData FirstData = 6 SecondData = 7 end enum Is there anyway that I can return the Enum names by their value, i.e., I want to input 6 into a function...
13
by: Don | last post by:
How do I get an Enum's type using only the Enum name? e.g. Dim enumType as System.Type Dim enumName as String = "MyEnum" enumType = ???(enumName)
1
by: Randy | last post by:
Hi, I downloaded and tried the ENUM++ code from CUJ http://www.cuj.com/documents/s=8470/cujboost0306besser/ but can't even get it to compile (see following). I have also downloaded and...
2
by: Randy | last post by:
Hi, I downloaded and tried the ENUM++ code from CUJ http://www.cuj.com/documents/s=8470/cujboost0306besser/ but can't even get it to compile (see following). I have also downloaded and...
34
by: Steven Nagy | last post by:
So I was needing some extra power from my enums and implemented the typesafe enum pattern. And it got me to thinking... why should I EVER use standard enums? There's now a nice little code...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.