'is' operator is giving compile error when used with switch statem

G

Guest

public static void HandleException(ref Exception io_exException,
bool
i_blnPropagateException)
{
switch (true)
{
case io_exException is ApplicationHandledException:
{
if (i_blnPropagateException)
{
throw io_exException;
}
break;
}
case io_exException is ApplicationBusinessException:
{
if (i_blnPropagateException)
{
throw io_exException;
}
break;
}
}
}

This function is not compiling coming with error "A constant value is
required". In the function 'ApplicationHandledException' and
'ApplicationBusinessException' are classes inherited from
System.ApplicationException.

Can someone please help me what is the reason and what is the way around? If
this is not possible what can be the alternative way?
 
N

Nick Hounsome

Raj said:
public static void HandleException(ref Exception io_exException,
bool
i_blnPropagateException)
{
switch (true)
{
case io_exException is ApplicationHandledException:
{
if (i_blnPropagateException)
{
throw io_exException;
}
break;
}
case io_exException is ApplicationBusinessException:
{
if (i_blnPropagateException)
{
throw io_exException;
}
break;
}
}
}

This function is not compiling coming with error "A constant value is
required". In the function 'ApplicationHandledException' and
'ApplicationBusinessException' are classes inherited from
System.ApplicationException.

Can someone please help me what is the reason and what is the way around?
If
this is not possible what can be the alternative way?

It means exactly what it says.

The way around it is to use if..then..else
 
J

Jay B. Harlow [MVP - Outlook]

Raj,
As the error message states, you need to put a constant value on the case
statement.

"io_exException is ApplicationHandledException" is not a constant
expression.

You may want to consider using a series of if statements instead:

if (io_exException is ApplicationHandledException)
| {
| if (i_blnPropagateException)
| {
| throw io_exException;
| }
| }
else if (io_exException is ApplicationBusinessException)
| {
| if (i_blnPropagateException)
| {
| throw io_exException;
| }
| }

I would consider checking blnPropagateException first, something like:

if (!i_blnPropagateException)
return;

if (io_exException is ApplicationHandledException)
throw io_exException;
else if (io_exException is ApplicationBusinessException)
throw io_exException;



--
Hope this helps
Jay B. Harlow [MVP - Outlook]
..NET Application Architect, Enthusiast, & Evangelist
T.S. Bradley - http://www.tsbradley.net


| public static void HandleException(ref Exception io_exException,
| bool
| i_blnPropagateException)
| {
| switch (true)
| {
| case io_exException is ApplicationHandledException:
| {
| if (i_blnPropagateException)
| {
| throw io_exException;
| }
| break;
| }
| case io_exException is ApplicationBusinessException:
| {
| if (i_blnPropagateException)
| {
| throw io_exException;
| }
| break;
| }
| }
| }
|
| This function is not compiling coming with error "A constant value is
| required". In the function 'ApplicationHandledException' and
| 'ApplicationBusinessException' are classes inherited from
| System.ApplicationException.
|
| Can someone please help me what is the reason and what is the way around?
If
| this is not possible what can be the alternative way?
|
 
L

Larry Lard

Raj said:
public static void HandleException(ref Exception io_exException,
bool
i_blnPropagateException)
{
switch (true)
{
case io_exException is ApplicationHandledException:
{
if (i_blnPropagateException)
{
throw io_exException;
}
break;
}
case io_exException is ApplicationBusinessException:
{
if (i_blnPropagateException)
{
throw io_exException;
}
break;
}
}
}

This function is not compiling coming with error "A constant value is
required". In the function 'ApplicationHandledException' and
'ApplicationBusinessException' are classes inherited from
System.ApplicationException.

Can someone please help me what is the reason and what is the way around? If
this is not possible what can be the alternative way?

C#'s switch statement is not the same as VB's Select Case statement. As
the message suggests, the former requires that the cases are constants.
This increases efficiency at the cost of flexibility. Given those two
poles, we all know which C# will choose and which VB will choose :)

Something that works with non-constant cases would just be short hand
for a series of if ... else ifs. Write it out like that, and it will
work.
 
G

Guest

Thanks for reply Nick.

I understand that the way around is to use if..then..else. But I want to use
switch statement because I am testing the same variable against lots of
values here I have given example with 2 cases so that it looks clear and
understandable.

I am trying some other way but if someone can give me any way of doing this
I would appreciate.

Regards
Raj
 
A

Alvin Bruney

There's a lot going on in this bit of code that you don't understand. My
advice to you is to first convert the statement into a simple if then else
construct. Once you understand what is going on, you can convert it back to
a switch.

For instance, the is operator returns a bool value, what you want is to use
the as operator. A throw statement transfers control out of scope, so you
shouldn't follow a throw with a break. Switch also requires a value of
integral type etc etc

--

________________________
Warm regards,
Alvin Bruney [MVP ASP.NET]

[Shameless Author plug]
Professional VSTO.NET - Wrox/Wiley
The O.W.C. Black Book with .NET
www.lulu.com/owc, Amazon
Blog: http://www.msmvps.com/blogs/alvin
 
G

Greg Young

I think its important that we look at why this doesn't work (as it would in
C)

we cannot even get a simpler version of this to work.

bool b = Convert.ToBoolean(args[0]);
bool b1 = Convert.ToBoolean(args[1]);
switch (true) {
case (b) :
break;
case (b1) :
break;
}


in fact we can never put a dynamic entry in as a case .. the reason for this
is that the compiler actually generates a lookup table for these items; they
are not processed as an "if" would be. We can see this by looking at the
following example.

string foo = "";
switch (foo) {
case ("test") :
break;
case ("bar") :
break;
}

which ildasms to ...

IL_0000: ldstr ""
IL_0005: stloc.0
IL_0006: ldstr "test"
IL_000b: ldstr "bar"
IL_0010: leave.s IL_0012
IL_0012: ldloc.0
IL_0013: dup
IL_0014: stloc.1
IL_0015: brfalse.s IL_0034
IL_0017: ldloc.1
IL_0018: call string [mscorlib]System.String::IsInterned(string)
IL_001d: stloc.1
IL_001e: ldloc.1
IL_001f: ldstr "test"
IL_0024: beq.s IL_0030
IL_0026: ldloc.1
IL_0027: ldstr "bar"
IL_002c: beq.s IL_0032
IL_002e: br.s IL_0034
IL_0030: br.s IL_0034
IL_0032: br.s IL_0034
IL_0034: ret

http://benjaminm.net/PermaLink.aspx?guid=10071512-7fa5-43eb-9bbc-5c345d0e13f5
explains more ..

Cheers,

Greg Young
MVP - C#
 
N

Nick Hounsome

Raj said:
Thanks for reply Nick.

I understand that the way around is to use if..then..else. But I want to
use
switch statement because I am testing the same variable against lots of
values here I have given example with 2 cases so that it looks clear and
understandable.

- You don't want or need "ref" in the parameter list.

- It looks like you can cut things down quite a bit by checking
i_blnPropagateException first.

- You should never need a lot of cases because you should have a nice
exception hierarchy and be catching base classes.

I would write it as something like:


if( i_blnPropagateException )
{
throw io_exException;
}
else if( io_exException is ApplicationHandledException )
{
}
else if( io_exEception is ApplicationBusinessException )
{
}
else
{
throw ....
}

I would suggest that ApplicationHandledException is fundamentally wrong. The
whole point of exceptions is that the thrower does not know how to handle
the situation - It is wrong for it to presume to know whether or not the
caller can or will handle it. If you just use ApplicationBase exception
instead then you can derive ApplicationBusinessException from that and
eliminate one case.
I am trying some other way but if someone can give me any way of doing
this
I would appreciate.

switch does what it does and only VB programmers seem to have a problem with
it.
[It is actually much more flexible than C/C++ switch because you can have
strings.]
 
S

Sericinus hunter

Raj said:
Thanks for reply Nick.

I understand that the way around is to use if..then..else. But I want to use
switch statement because I am testing the same variable against lots of
values here I have given example with 2 cases so that it looks clear and
understandable.

I am trying some other way but if someone can give me any way of doing this
I would appreciate.

If you really want to achieve switch/case look-and-feel, how about
throwing it once more and then catch again, but this time specifically?

public static void HandleException(ref Exception io_exException,
bool i_blnPropagateException)
{
try
{
throw io_Exception;
}
catch (ApplicationHandledException e)
{
if (i_blnPropagateException)
throw io_exException;
}
catch (ApplicationBusinessException e)
{
if (i_blnPropagateException)
throw io_exException;
}
}
 
B

Barry Kelly

Raj said:
This function is not compiling coming with error "A constant value is
required".

The switch statement requires constants in the case clauses.
Can someone please help me what is the reason and what is the way around? If
this is not possible what can be the alternative way?

Use a set of nested if statements instead.

-- Barry
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top