in java its possible to do something like this
class {
final int x = Random.randomInt();
final int y = Random.randomInt();
}
...
switch (intVariable)
{
case x: break;
case y: break;
}
as long as generateInt is final, this compiles.
is there an equivalent in C#?
edit: you might ask why i dont use concrete values or enums, but i have my reasons why the values are be random. ;)
with const you can't do that, it has to be a compile time constant.
You may use readonly, something like:
public class yourClass
{
public readonly int x = generateInt();
public static int generateInt()
{
return DateTime.Now.Millisecond; // or any other method getSomeInt();
}
}
EDIT:
Since the question is now edited and asks with reference to case expression in switch statement. You can't specify a variable or readonly in the case statement, it has to be constant expression/compile time constant.
From MSDN - Switch
Each case label specifies a constant value.
You may use if...else for your scenario.
Related
I know that case cannot work with non-constant values, but what should I do if its impossible to make a constant? thats my case: we have three variables, need to find that, one that will correspond to the value of the switch condition, but how to do this if the case is not able to work with non-constants? are there any workarounds?
float value = 4;
float number1 = 3, number2 = 6, number3 = 4;
switch (value)
{
case number1:
{
break;
}
case number2:
{
break;
}
case number3:
{
break;
}
}
here is the oversimplified example, and yes, you can easily do this using if/else if, but what if the number of values will be 100? what to do in that case?
One approach is to use an inverted Dictionary, where the key is the value and the value the key. Something like this:
var d = new Dictionary<int, int>();
d.Add(3, 1);
d.Add(6, 2);
d.Add(4, 3);
int keyPtr = d[value];
switch (keyPtr):
{
case 1:
//do something.
break;
case 2:
//do something else.
break;
case 3:
//do something different.
break;
}
Obviously this is simplified, and I have used int not float, but the same applies to any type. Using this technique,
your n variables, become the first n items in the Dictionary. In practice at the very least, you should check if your given value exists as a key in the Dictionary. It should help you in the right direction.
If you simply want to check whether your value variable equals to at least one of the variables number1, number2, number3, you could create an array of those numbers, say numbers[] and then create a method such as:
private bool checkValue(float value, float[] numbers) {
foreach (float num in numbers) {
if (num == value) return true;
}
return false;
}
This solution fits any number of elements in your numbers array.
If you want you can also use a List<float> instead of an array, so you could dynamically add more and more elements (Without a fixed size).
Is it possible in C# to define a variable like so?
switch(var num = getSomeNum()) {
case 1: //Do something with num
break;
default: break;
}
public static int GetSomeNum() => 3;
The documentation says that
In C# 6, the match expression must be an expression that returns a
value of the following types:
a char.
a string.
a bool.
an integral value, such as an int or a long.
an enum value.
Starting with C# 7, the match expression can be any non-null
expression.
To answer your question,
Yes you can switch on an int, e.g.
int myInt = 3;
switch(myInt)
Yes you can switch on the result of a method that returns an it, e.g.
int GetMyInt()
{
// Get my Int
}
switch(GetMyInt())
Yes you can switch on variable populated with a method result, e.g.
int GetMyInt()
{
// Get my Int
}
int myInt = GetMyInt();
switch(myInt)
No you can't do it like that.
I want control a other device with a C# program, this device have something like registers for read and write. So I searching something to enter all register numbers to get a better human readable code and to have central config place. All the registers using a uint value.
I searching something like this:
public enum EISCJoin : uint
{
Read_Connect = 1,
Read_Temp = 2,
Read_Switch = 3,
Write_Connect = 1,
Write_Temp = 2,
Write_Switch = 3,
}
switch (args.Sig.Number) //uint value
{
case (uint)EISC.Read_Connect:
{
args.SendValue[(uint)Write_Connect] = 1;
...
break;
}
case (uint)EISC.Read_Temp:
{
args.SendValue[(uint)Write_Temp] = 1;
...
break;
}
case (uint)EISC.Read_Switch:
{
args.SendValue[(uint)Write_Switch] = 1;
...
break;
}
}
My problem is that I don't want cast the ENUM value thousands of times in my source code and what I know is that a implicit conversation is not possible with enum.
Have someone a good idea to create a constant list of uint values?
you need to cast the number instead:
switch (args.Sig.Number)
to
switch ((EISCJoin)args.Sig.Number)
The other way is to use a static class and constant uints:
static public class EISCJoin
{
public const uint Read_Connect = 1;
public const uint Read_Temp = 2;
// and so on
}
I must work with a framework of the manufacturer and have no access to all the classes, it is not a option to modify all classes to the enum.
I using a value the most time only 1-2 times, so the most time I cast the value for 1 time use.
It looks like I must use the static class with the const uint variables.
Thanks for your help
The scenario is that I have say two different types of cases - case 1 and case 2. For case 1 and case 2 each I have a certain startIndex, endIndex and a formula for accessing the elements of a List.
Now for assigning values startIndex and endIndex I am preferring a normal switch case, however I am at loss for the formula for accessing elements. For case 1 it is say something like List[ a+i ] and for case 2 it is say List[a + (i-b)].
One way can be to have a for loop like this
for(int i=0;;i++)
{
if(case is 1)
then f=a+i
else if(case 2)
then f=a+(i-b)
}
I thought of using delegates. however, as per my knowledge they need to be made global. Actions do not return value. Func can be used but one expression/formula takes only one element (int) and the other takes 3. I need something in lines to this like that anonymous function can be assigned any of above mentioned formulae at runtime from the switch case (as the cases might and will increase in future).
Thank you.
I thought of using delegates. however, as per my knowledge they need
to be made global.
This is not true (actually, there are no truly global variables in C#, since each and every variable needs to be encapsulated inside an object). A public delegate type is indeed visible to all code after referencing the assembly containing this type's code, but a variable of such type can be private.
What I recommend in your situation is to have some sort of mapping from case numbers to delegates. A good idea is to use a Dictionary<TKey, TValue> if you have at most one delegate per case. This dictionary can be stored as a private variable inside the class where your method resides.
public class MyClass
{
private Dictionary<int, Delegate> _delegateMapping = new Dictionary<int, Delegate>;
}
There are a couple of ways you can add elements do the dictionary in the constructor: passing the already populated dictionary, passing an array of delegates, creating these delegates in the constructor itself. Either way, you'll end up with a dictionary of Delegate types, so you'll need to use a cast to be able to use them in your code properly.
for (int i = 1; i < _delegateMapping.Count; i++)
{
switch (i)
{
case 1:
var f = (Action<int>)_delegateMapping[1];
f(i);
break;
case 2:
var f = (Action<int, int>)_delegateMapping[2];
f(i, a);
break;
}
}
Of course I'm greatly improvising here.
It is important to note that if the type of delegate changes inside the dictionary, you will have to modify the cast accordingly inside the switch statement. Otherwise, if no implicit cast exists, you'll get a runtime exception.
Hi guys thank you so very much for your feedbacks. I finally found the solution with Func. This is what my code looks like. I had to manipulate the Func usage a little. I made almost all the vars which I have to use in the Func as global/local to the function where I write these Funcs. My apologies, if I was not able to explain my problem properly.
int i = -1;
Func<int,int> formula = null;
switch(f)
{
case 1:
{
formula = new Func<int,int>(index => { return i; });
}
break;
case 2:
{
formula = new Func<int, int>( index => { return s- (i * c); } );//here s and c are global variables.
}
break;
}
i = startIndex;
while(i < endIndex)
{
var Obj= List[formula.Invoke(i)];
//my code goes here
i++;
}
Let me know if my solution is correct w.r.t performance, logic, C# programming, etc.. :)
EDITED::
#usr and #Kapol I tried the way you suggested and tried to improvise the code like this.
private Dictionary<int, Func<int[], int>> indexFormulae;
private void assignDelegates()
{
indexFormulae = new Dictionary<int, Func<int[], int>>();
indexFormulae.Add(0, getFormula_1);
indexFormulae.Add(1, getFormula_2);
}
private void someFunction(int sp)
{
int i = 0;
Func<int[], int> formula = null;
indexFormulae.TryGetValue(formation,out formula);
i = startIndex;
while (i < endIndex)
{
int[] intValues = new int[] {i,sp,globalVar };
var Obj = List[formula.Invoke(intValues)];
//My code here
i++;
}
}
private int getFormula_1(params int[] intValues)
{
return intValues[0];
}
private int getIndex_Vertical(params int[] intValues)
{
return intValues[1] - (intValues[0] * intValues[2]);
}
So, that with this now I can use these two getFormula methods anywhere in this class rather than keeping them anonymous. and also I think I will stick to params because I might have N number of int params in future for other functions.
I need to get data bit width of a type. How can I get that?
For example how can I write a function as follows?
int x = 30;
Type t = x.GetType();
bool sign = IsSignedType(t); // int is signed type, so it's true
int width = GetWidth(t); // 32
For the size, you can use Marshal.SizeOf and multiply by the number of bits in a byte (hint: 8), though for the built-in value types it is probably easy enough and certainly faster to just use a case statement.
For the sign , I'd think bool sign = t == Math.Abs(t); would do.
EDIT:
To determine if it is a signed number, there is no built-in method, but there are only 3 5 of them:
public static class Application
{
public enum SignedEnum : int
{
Foo,
Boo,
Zoo
}
public enum UnSignedEnum : uint
{
Foo,
Boo,
Zoo
}
public static void Main()
{
Console.WriteLine(Marshal.SizeOf(typeof(Int32)) * 8);
Console.WriteLine(5.IsSigned());
Console.WriteLine(((UInt32)5).IsSigned());
Console.WriteLine((SignedEnum.Zoo).IsSigned());
Console.WriteLine((UnSignedEnum.Zoo).IsSigned());
Console.ReadLine();
}
}
public static class NumberHelper
{
public static Boolean IsSigned<T>(this T value) where T : struct
{
return value.GetType().IsSigned();
}
public static Boolean IsSigned(this Type t)
{
return !(
t.Equals(typeof(Byte)) ||
t.Equals(typeof(UIntPtr)) ||
t.Equals(typeof(UInt16)) ||
t.Equals(typeof(UInt32)) ||
t.Equals(typeof(UInt64)) ||
(t.IsEnum && !Enum.GetUnderlyingType(t).IsSigned())
);
}
}
#ChrisShain's answers the first part correctly. Assuming you can guarantee that t is a numeric type, to tell whether the type is signed or not you should be able to use expression trees to dynamically invoke the MaxValue const field on t, convert it to a bitarray and check to see if it uses the sign bit (or just use bitshift magic to test it without the conversion). I haven't done it this way but it should be doable. If you want an example, I can work through it.
Or do it the easy way with a switch statement (or series of ifs) like everyone else does.