How to Use Switch-Case on a Type

Switch case on type c#

Update C# 7

Yes: Source

switch(shape)
{
case Circle c:
WriteLine($"circle with radius {c.Radius}");
break;
case Rectangle s when (s.Length == s.Height):
WriteLine($"{s.Length} x {s.Height} square");
break;
case Rectangle r:
WriteLine($"{r.Length} x {r.Height} rectangle");
break;
default:
WriteLine("<unknown shape>");
break;
case null:
throw new ArgumentNullException(nameof(shape));
}

Prior to C# 7

No.

http://blogs.msdn.com/b/peterhal/archive/2005/07/05/435760.aspx

We get a lot of requests for addditions to the C# language and today
I'm going to talk about one of the more common ones - switch on type.
Switch on type looks like a pretty useful and straightforward feature:
Add a switch-like construct which switches on the type of the
expression, rather than the value. This might look something like
this:

switch typeof(e) { 
case int: ... break;
case string: ... break;
case double: ... break;
default: ... break;
}

This kind of statement would be extremely useful for adding virtual
method like dispatch over a disjoint type hierarchy, or over a type
hierarchy containing types that you don't own. Seeing an example like
this, you could easily conclude that the feature would be
straightforward and useful. It might even get you thinking "Why don't
those #*&%$ lazy C# language designers just make my life easier and
add this simple, timesaving language feature?"

Unfortunately, like many 'simple' language features, type switch is
not as simple as it first appears. The troubles start when you look at
a more significant, and no less important, example like this:

class C {}
interface I {}
class D : C, I {}

switch typeof(e) {
case C: … break;
case I: … break;
default: … break;
}

Link: https://blogs.msdn.microsoft.com/peterhal/2005/07/05/many-questions-switch-on-type/

How to use switch-case on a Type?

You cannot use a switch block to test values of type Type. Compiling your code should give you an error saying something like:

A switch expression or case label must be a bool, char, string,
integral, enum, or corresponding nullable type

You'll need to use if-else statements instead.

Also: typeof(int) and typeof(Int32) are equivalent. int is a keyword and Int32 is the type name.

UPDATE

If you expect that most types will be intrinsic you may improve performance by using a switch block with Type.GetTypeCode(...).

For example:

switch (Type.GetTypeCode(type))
{
case TypeCode.Int32:
// It's an int
break;

case TypeCode.String:
// It's a string
break;

// Other type code cases here...

default:
// Fallback to using if-else statements...
if (type == typeof(MyCoolType))
{
// ...
}
else if (type == typeof(MyOtherType))
{
// ...
} // etc...
}

c# 7.0: switch on System.Type

The (already linked) new pattern matching feature allows this.

Ordinarily, you'd switch on a value:

switch (this.value) {
case int intValue:
this.value = Math.Max(Math.Min(intValue, Maximum), Minimum);
break;
case decimal decimalValue:
this.value = Math.Max(Math.Min(decimalValue, Maximum), Minimum);
break;
}

But you can use it to switch on a type, if all you have is a type:

switch (type) {
case Type intType when intType == typeof(int):
case Type decimalType when decimalType == typeof(decimal):
this.value = Math.Max(Math.Min(this.value, Maximum), Minimum);
break;
}

Note that this is not what the feature is intended for, it becomes less readable than a traditional if...else if...else if...else chain, and the traditional chain is what it compiles to anyway. I do not recommend using pattern matching like this.

How to check control Type in Switch Case

As of C# 7 you can use type patterns for this:

private void CheckControl(Control ctl)
{
switch (ctl)
{
case TextBox _:
MessageBox.Show("This is My TextBox");
break;
case Label _:
MessageBox.Show("This is My Label");
break;
}
}

Here _ is the syntax for a discard, meaning you don't need to access the value as a TextBox (or Label) afterwards.

If you do want to access members of the specific type, you can introduce a pattern variable:

private void CheckControl(Control ctl)
{
switch (ctl)
{
case TextBox textBox:
// Use textBox for any TextBox-specific members here
MessageBox.Show("This is My TextBox");
break;
case Label label:
// Use label for any Label-specific members here
MessageBox.Show("This is My Label");
break;
}
}

How to use switch-case with strings in c#?

muvelet is a string while muvelet == "^" is a comarision which is boolean (it is either true or false

switch(muvelet)  
{
case "^":
// code for when it is equal to "^"
break;
//other cases
default:
//it is unknown character
}

note that the type in your switch (that is a string in this case) should match the type of cases

How to use a switch statement to narrow down a type using conditional types?

This is not currently possible in TypeScript. The control flow analysis which narrows the type of category does not act to narrow the type parameter IngredientCategory, and so there is no way for the compiler to deduce that Fruit is assignable to FoodFromCategory<IngredientCategory> even if category === "fruit".

The canonical issue asking for some solution here is probably microsoft/TypeScript#33912, and there are some specific feature suggestions which might allow this if implemented, such as microsoft/TypeScript#33014.


But for now, the compiler just cannot do this by itself, and if you want this to compile you will need to do something like a type assertion to tell the compiler that it can treat (for example) Fruit as FoodFromCategory<IngredientCategory>:

const castFood = <IngredientCategory extends Category>(
category: IngredientCategory, food: Food<any>
): FoodFromCategory<IngredientCategory> | undefined => {
switch (category) {
case "fruit":
return food as Fruit as FoodFromCategory<IngredientCategory>
case "grain":
return food as Grain as FoodFromCategory<IngredientCategory>
case "meat":
return food as Meat as FoodFromCategory<IngredientCategory>
}
return undefined
};

That works and suppresses the errors. But do note that this is you taking the responsibility for verifying type safety away from the compiler, and that you should be careful that you're doing it correctly.


Please note that, at runtime, the switch statement is doing nothing useful anyway. JavaScript doesn't know about Fruit or FoodFromCategory<IngredientCategory>; all that will be emitted to JavaScript as return food for each case. And if you're going to return food no matter what category is, you might as well write castFood this way instead:

const castFood = <IngredientCategory extends Category>(
category: IngredientCategory, food: Food<any>
) => food as FoodFromCategory<IngredientCategory>;

which completely eliminates the switch statement. It also eliminates undefined, since there's no valid way to call castFood() if category is not in IngredientCategory.

So that's the answer to the question as asked. Stepping back, I'm a little concerned that you're trying to do "cast"ing here at all; the category parameter is not used at runtime at all, so it's only to help the compiler determine what type food is supposed to be. But in that case you would probably be better off using Fruit | Grain | Meat as a discriminated union with the common category property and then test that property instead of passing it in as a separate parameter.

But without seeing how or why you plan to call castFood() I wouldn't presume to venture in that direction (but maybe it looks like this code). Instead, I'll just reiterate that narrowing generic type parameters via control flow is not currently possible, and that you will need to use type assertions or some other type-loosening technique to get this to compile.

Playground link to code

Is it possible to use the instanceof operator in a switch statement?

This is a typical scenario where subtype polymorphism helps. Do the following

interface I {
void do();
}

class A implements I { void do() { doA() } ... }
class B implements I { void do() { doB() } ... }
class C implements I { void do() { doC() } ... }

Then you can simply call do() on this.

If you are not free to change A, B, and C, you could apply the visitor pattern to achieve the same.

How to use Switch...Case in generic type parameter in C#?

If you need to know what the type of T is, you probably aren't using generics properly. Ask yourself: what happens if someone uses a T that you haven't accounted for?

It seems like what you need is to have a base class Response and then derive the other classes from it, then you can create a factory method which produces the appropriate instances of the derived classes depending on some logic.

Using Case/Switch and GetType to determine the object

If I really had to switch on type of object, I'd use .ToString(). However, I would avoid it at all costs: IDictionary<Type, int> will do much better, visitor might be an overkill but otherwise it is still a perfectly fine solution.



Related Topics



Leave a reply



Submit