Newbie Question about #define

  • Thread starter Thread starter Ben newsam
  • Start date Start date
B

Ben newsam

In defining a "colour space", I need a class with x and y components
of Red, Green, and Blue, and

also the x & y components of the "white point". In C++, I would do
something like this:

#define IlluminantC 0.3101, 0.3162
#define IlluminantD65 0.3127, 0.3291
#define IlluminantD93 0.2832, 0.2972


static CColourSpace NTSCSystem ( 0.67, 0.33, 0.21, 0.71, 0.14,
0.08, IlluminantC );
static CColourSpace SMPTEsystem ( 0.630, 0.340, 0.310, 0.595, 0.155,
0.070, IlluminantD65 );
static CColourSpace MySystem ( 0.64, 0.33, 0.29, 0.60, 0.15, 0.06,
IlluminantD65 );

CColourSpace::CColourSpace ( double dXR, double dYR, double dXG,
double dYG, double dXB, double dYB, double dXW, double dYW )
{
m_Red.m_dx = dXR;
<...Detail snipped...>
}

Notice how I am able to refer to, say, IlluminantD65 without having to
worry about the contents.

My question is of course, if you hadn't guessed already, how do I do
that in C#?
 
Ben,

You can't. There is no equivalent of the define statement in C#
(thankfully).

Rather, what you should do is create constants and read only fields
which have the values you wish. In this case, you would define constants
for the each of the IlluminantC components, and then pass those as
parameters to your constructor.

Hope this helps.
 
Ben,

You can't. There is no equivalent of the define statement in C#
(thankfully).

I agree that #defines in C/C++ are somewhat dangerous, in that they
are very often global and subject to being overwritten and so on.
Rather, what you should do is create constants and read only fields
which have the values you wish. In this case, you would define constants
for the each of the IlluminantC components, and then pass those as
parameters to your constructor.

Hope this helps.

Well, the point of the C++ code is that the Illuminant #defines are
x/y pairs, not mere single constants. The parameters to the
constructor are ordinary doubles, not a special Illuminant type. Using
a #define in this case causes a pair of doubles to be passed to the
constructor, but in an "information hiding" way.

How should the C# code look to do this, then?
 
Ben newsam said:
On Tue, 12 Sep 2006 13:51:53 -0400, "Nicholas Paldino [.NET/C# MVP]"


Well, the point of the C++ code is that the Illuminant #defines are
x/y pairs, not mere single constants. The parameters to the
constructor are ordinary doubles, not a special Illuminant type. Using
a #define in this case causes a pair of doubles to be passed to the
constructor, but in an "information hiding" way.

How should the C# code look to do this, then?

The better question is:
Why are you doing it in the C++ code???

A single #define expanding into 2 comma separated doubles...uuuuuhggghhh
(makes me shudder just to think of it)

You showed this as a sample:
static CColourSpace SMPTEsystem ( 0.630, 0.340, 0.310, 0.595, 0.155,
0.070, IlluminantD65 );

That certainly LOOKS like a function taking 7 parameters...but NO it
really takes 8.

There are far better (more understandable/maintainable) ways of doing
this.

Bill
 
Ben newsam said:
On Tue, 12 Sep 2006 13:51:53 -0400, "Nicholas Paldino [.NET/C# MVP]"


Well, the point of the C++ code is that the Illuminant #defines are
x/y pairs, not mere single constants. The parameters to the
constructor are ordinary doubles, not a special Illuminant type. Using
a #define in this case causes a pair of doubles to be passed to the
constructor, but in an "information hiding" way.

How should the C# code look to do this, then?

The better question is:
Why are you doing it in the C++ code???

I'm not. I am translating it all into C#
A single #define expanding into 2 comma separated doubles...uuuuuhggghhh
(makes me shudder just to think of it)

So... you're not going to answer my question, then? :-/
 
Ben said:
Well, the point of the C++ code is that the Illuminant #defines are
x/y pairs, not mere single constants. The parameters to the
constructor are ordinary doubles, not a special Illuminant type. Using
a #define in this case causes a pair of doubles to be passed to the
constructor, but in an "information hiding" way.

Yes, but the #define hides not just the values of the Illuminant but
also the structure. This is going to mess up auto-completion and
parameter tooltips, and probably leads to some baffling error
messages.
How should the C# code look to do this, then?

A special Illuminant type, of course. The ColourSpace space
constructor could be overloaded, with one overload taking 8 doubles
and another taking 6 doubles and an Illuminant. Then Illuminant.C,
Illuminant.D65, and Illuminant.D93 would just be public static
Illuminant values.

Something like this:

struct Illuminant
{
public double X;
public double Y;

public Illuminant(double X, double Y)
{
this.X = X;
this.Y = Y;
}

public static Illuminant C = new Illuminant(0.3101, 0.3162);
public static Illuminant D65 = new Illuminant(0.3127, 0.3291);
public static Illuminant D93 = new Illuminant(0.2832, 0.2972);
}
 
A special Illuminant type, of course. The ColourSpace space
constructor could be overloaded, with one overload taking 8 doubles
and another taking 6 doubles and an Illuminant. Then Illuminant.C,
Illuminant.D65, and Illuminant.D93 would just be public static
Illuminant values.

Something like this:

struct Illuminant
{
public double X;
public double Y;

public Illuminant(double X, double Y)
{
this.X = X;
this.Y = Y;
}

public static Illuminant C = new Illuminant(0.3101, 0.3162);
public static Illuminant D65 = new Illuminant(0.3127, 0.3291);
public static Illuminant D93 = new Illuminant(0.2832, 0.2972);
}


Thanks a lot. I had almost solved it myself with a pair of classes
(XYPair and Illuminant) in a way that looked superficially similar,
but I really like the neat trick of a struct containing instances of
itself. It's a bit incestuous, but hey, it's neat, and it works too.
Thanks again.
 
Ben said:
Thanks a lot. I had almost solved it myself with a pair of classes
(XYPair and Illuminant) in a way that looked superficially similar,
but I really like the neat trick of a struct containing instances of
itself. It's a bit incestuous, but hey, it's neat, and it works too.
Thanks again.

You probably want

public static readonly Illuminant C = new Illuminant(0.3101, 0.3162);
public static readonly Illuminant D65 = new Illuminant(0.3127, 0.3291);
public static readonly Illuminant D93 = new Illuminant(0.2832, 0.2972);

so that no other code can say:

Illuminant.C = new Illuminant(...);
 
You probably want

public static readonly Illuminant C = new Illuminant(0.3101, 0.3162);
public static readonly Illuminant D65 = new Illuminant(0.3127, 0.3291);
public static readonly Illuminant D93 = new Illuminant(0.2832, 0.2972);

so that no other code can say:

Illuminant.C = new Illuminant(...);

Thanks. Good point. It all seems to work well now, and I can progress.
Now I have:

public static readonly ColourSpace sRGB = new ColourSpace(0.64, 0.33,
0.30, 0.60, 0.15, 0.06, Illuminant.D65);

too! Thanks to everyone.
 
Ben newsam said:
I'm not. I am translating it all into C#


So... you're not going to answer my question, then? :-/

Oops...sorry about that. I was sort of short on time at the moment.
Luckily, others here have given you the help that I should have :(

Good luck with the conversion
Bill
 
Back
Top