I'm trying to get my code to check whether or not a certain string is in the enumerated type. This is what I have:
public enum CurrencyAmt {twenty(20), ten(10), five(5), toonies(2), toony(2), loonies(1), loony(1), quarters(0.25),
quarter(0.25), dimes(0.1), dime(0.1), nickels(0.05), nickel(0.05), pennies(0.01), penny(0.01);
private int type;
private double value;
CurrencyAmt (int i)
{
this.type = i;
}
CurrencyAmt (double i)
{
this.value = i;
}
}
defines my enum type. And the expression
(Enum.IsDefined(typeof(CurrencyAmt), inputAt)
to check if the string 'inputAt' is in the enum. However, i receive the error CurrencyAmt cannot be resolved to a variable. Any ideas?
You need a .class after CurrencyAmt, I reckon:
(Enum.IsDefined(typeof(CurrencyAmt.class), inputAt)
However, as I don't recognise any other parts of this code snippet from Java, I think the Java version should be:
CurrencyAmt.valueOf(inputAt);
...which will return the CurrencyAmt enum constant that corresponds to the given string or will throw an exception if it's not defined.
Related
I'm trying to do a bit of factoring on my use of a series of Enums defined in .net
private static String GetSystemTranslatedField(Type enumtype, int? val) {
if (val == null)
return "";
int value = (int)val;
String tempstr;
if (Enum.IsDefined(enumtype, value))
{
tempstr = (String) enumtype.GetMethod("ToString",Type.EmptyTypes).Invoke(val,null);
//equivalent to ((enumtype)val).ToString();
}
}
The problem is that when trying to run this, i get the infamous System.Reflection.TargetException: Object does not match target type.
As an extra question, is there a way to change the signature of my method so that only types deriving from Enum are accepted? It's not a big concern but i got curious about type restriction and couldn't find anything.
You are trying to call ToString coming from an enum type on an Int32 which is causing an exception in the Reflection API.
If you want to get the identifier related to a value, use Enum.GetName which will work on int's as well (although the documentation does not seem to indicate this):
if (Enum.IsDefined(enumtype, value))
{
tempstr = Enum.GetName(enumType, value);
}
In fact it will return the empty string if the value is not defined, so that if could be removed as well (depending on what is in the rest of the code):
tempstr = Enum.GetName(enumType, value);
C# does not allow generic constraints to Enum derived types. It is doable on a theoretical level (it is not disallowed by the CLR) however it requires some IL weaving, which Jon Skeet demonstrated in his Unconstrained Melody project.
Enum is a class, so you can set that as your base for method signature and avoid reflection entirely. Try:
private static String GetSystemTranslatedField(Enum enumtype, int? val) {
if (!val.HasValue)
return "";
String tempstr;
if (Enum.IsDefined(enumtype, val.Value))
{
tempstr = ((enumtype)val.Value).ToString();
}
... // Rest of your code here
}
Note that I cleaned your method up a bit, mainly cosmetic stuff.
My question is very similar to : Cast to type known only at runtime , however that one was not really answered (it's also in C rather than C#).
I'm writing something to control some hardware, and depending on the given hardware configuration I have to do some bitwise arithmetic with a "byte" or "UInt32" type. The bit arithmetic code is long but identical in the 32bit and 8bit case, with the only difference being the length of certain loops (32 or 8).
My current solution is to use a switch, which means I have pretty much two copies of the same code in a giant if statement.
An alternative solution is to use an array or 0s and 1s rather than a UInt32 or byte to do the bitwise operations and then convert to UInt32 or byte at the end.
The last solution, which I'm most interested in here, is to dynamically pick which type I will use at runtime. Here is some pseudocode for what I would like:
System.Type MyType;
if (something)
MyType=type1;
else
MyType=somethingElse;
myType someVariable; //Create a variable of type myType. This line will give an
//error
someVariable=(myType) otherVariable //do an example typecast with the
//runtime-determined type
I've searched around to know that the answer may have something to do with generics and reflection, but I can't figure out how to do it exactly.
You might consider using a BitArray for this - you can initialise it from a byte or uint32, do the bitwise operations, and then convert it back at the end e.g.
object value;
bool isByte = value is byte;
BitArray ba = isByte
? new BitArray(new byte[] { (byte)value })
: new BitArray(BitConverter.GetBytes((unint32)value));
...
I would probably create an abstract class, something like HardwareConfigBase which includes your looping code as well as the size of the loop. Then have 2 child classes that extend that base class.
public abstract class HardwareConfigBase
{
protected int TimesToLoop;
public byte[] Data = new byte[32 * 8]; //Size of UInt, but still works for 8bit byte
public void MyLoopCode
{
for(int i = 0; i < TimesToLoop; i++)
{
//Do whatever
}
}
}
public class ByteHardwareConfig
{
public ByteHardwareConfig
{
TimesToLoop = 8;
}
}
public class UIntHardwareConfig
{
public UIntHardwareConfig
{
TimesToLoop = 32;
}
}
public void Main()
{
var myHardwareConfig = new ByteHardwareConfig(); //Could also be UInt
//Do some more initialization and fill the Data property.
myHardwareConfig.MyLoopCode();
}
You can create an instance of a type at runtime using Activator.CreateInstance() like so:
object myInstance = Activator.CreateInstance(MyType);
Then, see this question for how to do a type cast at runtime using only runtime-known types.
public static dynamic Convert(dynamic source, Type dest) {
return Convert.ChangeType(source, dest);
}
myInstance = Convert(myInstance, MyType);
// will result in myInstance being of type MyType.
The answer is rather pretty simple. You will not need to cast or convert any variables at runtime in order to be able to modify uint or byte types at runtime. The following three definitions will suffice.
The first class definition is the Provider class which defines two methods, each one to modify either a variable of uint or byte type. Be sure to put your modifying logic inside the methods.
class Provider
{
public uint GetResult(uint c)
{
return c;
}
public byte GetResult(byte c)
{
return c;
}
}
The next class is the one that will invoke the appropriate method from the previous class definition, depending on the type of the parameter you provide.
class Execute
{
public object GetResult(object source)
{
var provider = new Provider();
return provider.GetType()
.GetMethods()
.Where(x => x.Name == "GetResult" && x.ReturnType == source.GetType())
.First()
.Invoke(provider, new object[] { source });
}
}
The last definition is here to simply test how this setup works. You can see that we have both a byte and a uint type. Passing them both to the GetResult(object) method yields the expected results, and as you can see, the underlying system type is also as expected.
class Program
{
static void Main()
{
uint u = 1;
byte b = 2;
var result1 = new Execute().GetResult(u);
var result2 = new Execute().GetResult(b);
sc.WriteLine(result1 + " " + result1.GetType().UnderlyingSystemType);
sc.WriteLine(result2 + " " + result2.GetType().UnderlyingSystemType);
sc.Read();
}
}
Try using the dynamic keyword in C#.
dynamic myType;
if (a) {
myType = new type1();
} else {
myType = new type2();
}
I'm having this problem and searching for solutions, but didn't find a situation similar to mine.Here's what I have:
in a class file X.cs:
namespace BlaBla{
public class X{
public const string foo = "foo";
// other code
}
public class Y{
public const int bar = 0;
}
}
and in some other class, I'm writing:
private const string someString = X.foo + Y.bar + "";
it keeps giving me a compile error:
The Expression assigned to someString must be constant
although they are both constant! when I remove Y.bar the error is removed and I dont know why. Any help ?
You're using the const keyword wrong. You probably want to define someString as:
private readonly someString = X.foo + Y.bar;
When a variable is marked as const they are compiled in to the assembly and then optimised. While Y.bar is defined as const, you're implicitly invoking its ToString() method which makes it not constant.
You're including a conversion from int to string. Even though the int is a constant, the conversion isn't considered a constant expression.
You can demonstrate that more simply:
class Test
{
const int X = 10;
const string Y = "X: " + X;
}
See section 7.19 of the C# specification for more details about what counts as a constant expression.
The expression looks constant, but it requires evaluation so that value can be figured out.
I have a following function which accepts a enum value and based upon the enum value returns a constant value(which is in a different class). Now i get a "Constant initializer missing" Error.
public const int Testfunction(TESTENUM TestEnum)
{
switch(TestEnum)
{
case TestEnum.testval1:
return testclass.constvalue;
case TestEnum.testVal2:
return testclass.constvalue1;
case TestEnum.testVal3:
return testclass.constvalue2;
}
}
how exactly the function's return type would be? (I am using object return type and this does not throw any error)
Is there any other option to achieve the same?
What's happening here is the compiler thinks that you are trying to declare a public constant integer field named Testfunction, and is extremely surprised to discover that there is no = 123; following the identifier. It's telling you that it expected the initializer.
There are a number of places in the C# compiler where the development team anticipated that C and C++ users would use a common C/C++ syntax erroneously. For example, there's a special error message for int x[]; that points out that you probably meant int[] x;. This is an example of another place where the compiler could benefit from a special-purpose error message that detects the common mistake and describes how to fix it. You might consider requesting that feature if you think it's a good one.
More generally, "const" in C# means something different than it means in C or C++. C# does not have the notion of a "const function" that does not mutate state, or a "const reference" that provides a read-only view of potentially-mutable data. In C# "const" is only used to declare that a field (or local) is to be treated as a compile-time constant. (And "readonly" is used to declare that a field is to be written only in the constructor, which is also quite useful.)
Removing "const" keyword from your function return type should solve the problem
It should be like this
public int Testfunction(TESTENUM TestEnum)
{
...
Return type cannot be declared constant
.NET methods cannot return const any type..
The const keyword is invalid there: remove it.
The most likely working code:
public static class TestClass
{
public const int constValue1 = 1;
public const int constValue2 = 2;
public const int constValue3 = 3;
}
enum TestEnum
{
testVal1, testVal2, testVal3
}
public int TestFunction(TestEnum testEnum)
{
switch (testEnum)
{
case TestEnum.testVal1:
return TestClass.constValue1;
case TestEnum.testVal2:
return TestClass.constValue2;
case TestEnum.testVal3:
return TestClass.constValue3;
}
return 0; // all code paths have to return a value
}
First, according to const (C# Reference):
The const keyword is used to modify a declaration of a field or local variable. It specifies that the value of the field or the local variable is constant, which means it cannot be modified.
In C#, const is only used as a modifier of a field (like TestClass.constValue1) or local variable, not suitable for a function return type.
So you are from the great C/C++ kingdom. Thinking with my very limited knowledge to C/C++, const return types in C/C++ is only meaningful with pointers...
// C++ code
const int m = 1;
// It returns a pointer to a read-only memory
const int* a(){
return &m;
}
But unless you are using unsafe code, there is no pointer in C#. There are only value types (like int/DateTime/TestEnum/structs) and reference types (like string/classes). There are a lot more to read about on the web.
So as int is a value type in C#, when you returns it, it gets copied. So even if you are returning a "constant int" the returned value is not a constant and modifying the return value will not "change the constant and cause a SegFault".
Well, I forgot to answer your questions...
How exactly the function's return type would be? (I am using object return type and this does not throw any error)
Like what I showed in the code above, int.
const int blah = 1 only declares a variable/field blah of type int which one must not modify it (by doing blah = 2). In C# const int is not a type.
Is there any other option to achieve the same?
Well... I think I don't actually need to answer this...
So... I want to return value when C# function is called. I need a code example (simple summ of a,b values will be ok) Please help
I need something like this ( I know ActionScript so I will write in it):
public function sum(valueA:int, valueB:int):int
{
var summ:int = valueA + valueB;
return summ;
}
How to translate it into C#?
Here:
public int sum(int valueA, int valueB)
{
int summ = valueA + valueB;
return summ;
}
Differences to note:
The return type is declared immediately after the public visiblity qualifier
Variable types are declared before them
As a side-note, C# (3.0 above) also supports the var keyword when declaring variables, which means that you can write:
public int Sum(int valueA, int valueB) {
var summ = valueA + valueB;
return summ;
}
The meaning of var is porbably different than in ActionScript - it looks at the expression used to initialize the variable and uses the type of the expression (so the code is statically-typed). In the example above, the type of summ will be int just like in the version posted by Oded.
(This is often a confusing thing for people with background in dynamic languages, so I thought it would be useful to mention this, especially since var is also a keyword in ActionScript).
Or even so =)
public int Sum ( int valueA, int valueB ) { return valueA + valueB; }
if you don't need to store a result in a function for some purpose.