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
Why Cannot Ienumerable<Struct> Be Cast as Ienumerable<Object>
.Net - Windowstyle = Hidden VS. Createnowindow = True
Automatic Native and Managed Dlls Extracting from Nuget Package
How to Generate a Cryptographically Secure Pseudorandom Number in C#
Is There Windows System Event on Active Window Changed
Openxml Sdk Returning a Number for Cellvalue Instead of Cells Text
ASP.NET Core API Only Returning First Result of List
System.Data.Sqlclient.Sqlexception: Login Failed for User
Why Datetime.Addhours Doesn't Seem to Work
Performing Inserts and Updates with Dapper
Generate a Self-Signed Certificate on the Fly
How to Do a Sha1 File Checksum in C#
Async/Await Different Thread Id
How to Do .Net Binary Serialization of an Object When You Don't Have the Source Code of the Class
Wpf Databinding to Interface and Not Actual Object - Casting Possible