Hey guys im not sure if what i want to do is right or not,
i have diffrent status in our network,which i have created a ENUM class for it:
public enum AllMachinesStatus
{
STOP,
START,
LINKDOWN,
ERROR,
LINK_UP,
IDLE,
}
in database i there is a service which binds these fields,they are all int,the show the number of the machine in each status which should vary from time to time,,now i want to get this data with linq and bind my class,do you think its a right way?or i should create a normal class with a constructor which whenever i call the class i can have the data?
var rslt=(from s in db.Machines
select new AllMachinesStatus{
//here i dont have access to the properties of enum class to bind them with Count()
}
If s in an integer with a valid value for AllMachinesStatus, try:
from s in db.Machines select (AllMachinesStatus)s
Basically, it is casting the int to AllMachinesStatus enum
Your issue is improper usage of enum here.
enum does not have a constructor, it is a strong type that has an implicit value type, but it is mostly suitable for signaling and flagging.
In this method, you would evaluate on s and either cast the correlating int value of s or a field\property of s to AllMachinesStatus or do Enum.Parse using s or a field\property of s (i.e. s.Status).
note that AllMachinesStatus enum has implicit int values.
public enum AllMachinesStatus
{
STOP, // 0
START, // 1
LINKDOWN, // 2
ERROR, // 3
LINK_UP, // 4
IDLE, // 5
}
Example of Enum.Parse with s.Status
// note that 'false' is being passed for case insensitive behavior in the method
var rslt=(from s in db.Machines
select (AllMachinesStatus)Enum.Parse(typeof(AllMachinesStatus), s.Status, false));
Alternatively,
if s had a field (I'll call BitFlag for purpose of example) correlating to the int value, you could us the following:
Example of casting int to AllMachinesStatus
var rslt=(from s in db.Machines
select (AllMachinesStatus)s.BitFlag);
Doc References:
MSDN System.Enum
MSDN Enum.Parse
EDIT1:
Include examples and corrected sentiment of using Enum.GetName to Enum.Parse
EDIT2:
update s to use question comment referenced s.Status existence.
Related
I 'm new to C#. Is there any way to create a function that can change the datatype of a variable to an another datatype and return the changed value.
I don't want to use the built-in Convert class.
For example :
Let's assume that ChangeDataType is the name of the function. It should also be possible to do the same thing with all datatypes.
int a = 5;
float b = ChangeDataType(a, "float"); // 5.0
Thanks.
Please note that you cannot change data type of already declared variable. But you can create new variable of desired type and then typecast old variable into new one. If this type casting fails, then invalidcastexception is thrown.
Below are different kinds of typecasting options:
1. Implicit Type casting
In this you don't need to use any syntax.
For ex:
int i = 10;
float a = i;
2. Explicit Type casting
You need to specify the type in which you want to convert to. For ex:
class Test
{
static void Main()
{
double x = 1234.7;
int a;
// Cast double to int.
a = (int)x;
System.Console.WriteLine(a);
}
}
// Output: 1234
3. User Defined Casts
Using implict and explicit keywords in c#.
Please refer
4. Helper Classes
There are many classes which provides method to convert data types.
One of the important class is - Convert.
This class provides a lot of methods. Convert.ToString, Convert.ToInt32, etc.
Another example is TryParse methods in int, long, double, DateTime, etc classes. Please refer
I set the following property:
public Object Value
{
get
{
return AdministrationSettings.Default[settingCode];
}
set
{
AdministrationSettings.Default[settingCode] = value; // <<< Error occurs here
this.RaisePropertyChanged(() => this.Value);
}
}
This property provides the link between the fields of my interface and those of the object AdministrationSettings
AdministrationSettigs represents Settings class .net (having an extension .Settings)
Inside I defined within the properties here is an example:
When I made the entered data in a field in my interface, here display this interface:
the program stops at the instruction of line 9, and generates this error:
The settings property "ExclusionZone" is of a non-compatible type, here the code
the ExclusionZone is one parameter which defined in the .Settings File. its type is double. It is also in the same file (. Settings) they set other parameters, there are those who are of type string, double, Boolean
the problem is only in the Set, for the Get get it's right
I hope there will be someone who can help me
Thanks
private int value = Convert.ToInt32(Properties.Settings.Default.Setting);
Properties.Settings.Default["Setting"] = value + 1;
This crashed for me but when I changed to value + 1.tostring(); It worked. Ofcourse because my "setting" is of type string. So check that ur value is of the right type :)
First of all you might want to change the manner in which you are trying to access the application level properties that you defined.
As alexander points out try: Properties.Settings.Default["PropertyVariable"] instead of AdministrationSettings.Default["PropertyVariable"]
Secondly you have defined three properties namely: (1) ExclusionZone, (2)AlertZone (3)ExcessiveSpeed but you are trying to access 'settingCode' which is not defined.
Thirdly you are missing inverted commas.
Once you sort these three things, make sure you cast 'value' to the correct data type.
I use ProfileBase to get and maintain extra settings in a user profile. The ProfileBase object that you get from the ProfileBase.Create() function seems to return something like a dictionary of string-to-string. Therefore, when I make changes to values and save them, I have to cast them to string, and then call the Save() function on the ProfileBase object. Here's me saving a bool flag, but first converting it to an int (1 or 0) and then saving that as a string...
ProfileBase pb = ProfileBase.Create(userNew.UserName, true);
if (pb != null)
{
int iCreateFlag = createDefaultDummyAccounts ? 1 : 0;
pb["CREATEDEFAULTDUMMYACCOUNTS"] = iCreateFlag.ToString();
pb.Save();
}
If I do not cast iCreateFlag to string, and I try to save the iCreateFlag as an int, I get "The settings property is of a non compatible type", even though my column is defined in the database as INT. Hope this helps anyone else out with this problem.
Bear with me as this is a difficult concept for me. I have a method that returns the items in an enum as strings (for DB storage). Here is the method:
public static IEnumerable<SelectListItem> GetItemsFromEnum<T>
(T selectedValue = default(T)) where T : struct
{
return from name in Enum.GetNames(typeof(T))
let enumValue = Convert.ToString((T)Enum.
Parse(typeof(T), name, true))
select new SelectListItem
{
Text = GetEnumDescription(name, typeof(T)),
Value = enumValue,
Selected = enumValue.Equals(selectedValue)
};
}
(NB: GetEnumDescription is another method in the class that gets the [Display(Name="") text to display something friendly in the UI.)
For a single select input (radio button, drop down), this works great. However, with multi-selects (list box, check box list), I am thinking of using the enum [Flags] attribute to store in the DB as an int.
However, the GetItemsFromEnum method will not work in the case that I use [Flags] and requires that I change it so that the value assigned in the GetItemsFromEnum method isn't the string value of the enum, it's the int value.
This is actually a two-parter:
How can I modify the method so that enumValue would be the
value of the int from enum [Flags] (i.e., if "1 + 2" were selected
(two check boxes), then the int value saved would be "3")?
Most importantly, what kind of logic can I insert in the method
so that all my other enum's (those without [Flags]) are not
affected (i.e., it still converts ToString)? I was thinking some if ... else logic, but would that work?
First of all, the [Flags] attribute doesn't add special properties to the enum's values, it's just used through Reflection by the Enum class when formatting it as a string and to let people who use your code know that they can use bitwise operations on the enum safely, or in other words, without undesired results.
Let's take this enum:
[Flags]
enum MyEnum
{
Undefined,
Employee,
Student
}
And let's create a variable this way:
var employeeAndStudent = MyEnum.Employee | MyEnum.Student;
The variable, if cast to integer, is equals to 3. While the ToString() method will print "Employee, Student", Enum.GetNames doesn't have a value assigned for the field 3 -- Quite obviously, since it has no name. I can think of two solutions:
You create your own GetNames which will return, in addition to the defined names, also all the possible combinations of the enum's values, conveniently printed in your format.
You define the flags in the enum, which can become pretty wasteful if there are many members. In our case, MyEnum would become:
[Flags]
enum MyEnum
{
Undefined,
Employee,
Student,
EmployeeAndStudent
}
One more thing, your method seems to have a bug. This line:
Selected = enumValue.Equals(selectedValue)
Is trying to compare an enum type to a string, and will always result in false. Are you sure that SelectListItem.Value should be of type string? I suggest you to review your code.
To give direct answers to your question:
Add [Flags] to your enum and use the OR operator to combine values.
In your GetEnumDescription method, check if the type has the Flags attribute.
I'm bone new to generics in C#, and I'm attempting to create a method that will use generics. I tripped across the where keyword when attempting to create a local variable, so I'm sure that it will be part of the solution.
The reason for this is I have several different enum variables but the method would do the same to each (given a string that is one of the enum's defined values, toggle it on, using the enum like a bit field).
I have most of this together, the part I'm now stuck at is being able to tell the generic method it's ok to allow "|=" as I'm certain any type passed in will support the operator.
I would like to be able to maintain generality, if possible, so could either be an enum or a List and I would execute different code paths depending on the type.
Example of what I'm taking about
enum someType { value1 = 1<<0, value2 = 1<<1, value3 = 1<<2 }; // and so on
// some more enums
private T someMethod<T>(string myIdentifyers)
where T: new()
{
// suppose myIdentifiers is 1 more more of the valid enum options
// assume that the correct strings and enum combinations will be passed
T retval = new T();
while () {
// assume a loop with a method call that parses off one identifyer at a time
// if I have to convert the enum to an int first, so be it, but
// at this point I can't tell it that a cast to int exists
retval |= (T)System.Enum.Parse( typeof(T), oneIdentifyer, false );
}
return retval;
}
I would try something like this (pseudocode):
[Flags]
enum someType { value1 = 1<<0, value2 = 1<<1, value3 = 1<<2 }; // and so on
// some more enums
private T someMethod<T>(string myIdentifyers)
where T: struct, new()
{
// check if enum
if (typeof(T).BaseType != typeof(Enum)) // we should probably check for the flags attribute too
throw new Exception();
// suppose myIdentifiers is 1 more more of the valid enum options
// assume that the correct strings and enum combinations will be passed
int retval = 0;
while () {
// assume a loop with a method call that parses off one identifyer at a time
// if I have to convert the enum to an int first, so be it, but
// at this point I can't tell it that a cast to int exists
retval |= (int) (object) System.Enum.Parse( typeof(T), oneIdentifyer, false );
}
return (T) (object) retval;
}
It's not possible to express enum generic-constraints as of C# 4. Nor is it possible to express operator-constraints.
That said, I think you're looking for a method like this:
public static T AssembleFlagsEnum<T>(IEnumerable<string> names) where T : struct
{
return (T)(object)names.Aggregate(0,
(valSoFar, name) => valSoFar | Convert.ToInt32(Enum.Parse(typeof(T), name)));
}
Note that this doesn't validate that the type is a [Flags] enum. Nor will it work for enums which have underlying-types other than int.
In general, there's no good way to invoke operators on a generic type, although there are some kludges and workarounds that can help out in some circumstances.
See this similar question: Generic C# Code and the Plus Operator
In this case, since you know your enums cast to and from int, I think Bruno's method is the way to go.
Unfortunately it's not possible.
You can restrict with the struct constraint to say value type but obviously that includes more than integers. The only thing you could then do is early in the code to check on the actual type.
Supported constraint restrictions are described at http://msdn.microsoft.com/en-us/library/d5x73970.aspx
You can't do operator constraints - see Solution for overloaded operator constraint in .NET generics
EDITED: Updated 3/23/09. See rest of post at bottom. I'm still having trouble with the indexer. Anymore help or examples would really help me out.
Write a class, MyCourses, that contains an enumeration of all the
courses that you are currently taking.
This enum should be nested inside of
your class MyCourses. Your class
should also have an array field that
provides a short description (as a
String) of each of your courses. Write
an indexer that takes one of your
enumerated courses as an index and
returns the String description of the
course.
Write a class MyFriends that contains an indexer that provides
access to the names of your friends.
namespace IT274_Unit4Project
{
public class MyCourses
{
// enumeration that contains an enumeration of all the courses that
// student is currently enrolled in
public enum CourseName {IT274= 0,CS210 = 1}
// array field that provides short description for each of classes,
// returns string description of the course
private String[] courseDescription =
{"Intermediate C#: Teaches intermediate elements of C# programming and software design",
"Career Development Strategies: Teaches principles for career progression, resume preparation, and overall self anaylsis"};
// indexer that takes one of the enumerated courses as an index
// and returns the String description of the course
public String this[CourseName index]
{
get
{
if (index == 1)
return courseDescription[0];
else
return courseDescription[1];
}
set
{
if (index == 1)
courseDescription[0] = value;
else
courseDescription[1] = value;
}
}
}
}//end public class MyCourses
I'm working on this homework project and having trouble understanding the text explaining how to correctly take the accessed value of the enumeration and then apply the string array value to it. Can you please help me understand this? The text we are using is very difficult and poorly written for a beginner to understand, so I'm kind of on my own here. I've got the first parts written, but need some help on the accessing of the enumeration value and assigning, i think i'm close, but don't understand how to properly get and set the values on this.
Please do not provide me with direct code answers, unless a MSDN style explanation that is generalized and not specific to my project. ie:
public class MyClass
{ string field1;
string field2;
//properties
public string Value1
get etc...
Thanks!
First of all, the base type of an enumeration has to be a numeric value type, so you can't have an enumeration with base type string. The following isn't going to compile:
public enum CourseName
{
Class1 = "IT274-01AU: Intermediate C#",
Class2 = "CS210-06AU: Career Development Strategies"
}
So change it to use the default base type of int. Something like the following will do, but change the names as you see fit (you might want to use the course name instead of the code, for example). Remember also that you should use meaningful names whenever possible in an enumeration.
public enum Courses
{
IT274_01AU,
CS210_06AU
}
(I know you said you didn't want specific code examples, but I think this one illustrates my point much more clearly than any explanation.)
Second, you're on the right track with the indexer, but you have to think of how to relate the enumeration to the array of string descriptions. Remember, an enumeration is nothing more than a finite set of glorified (named) numbers. With the above Courses enumeration, you have two values named IT274_01AU and CS210_06AU. So in the indexer, you have to map each of these values to the string description. There are multiple ways to do it, but the simplest one would be a switch statement, for example:
switch (myEnum)
{
case value1:
return string1;
case value2:
return string2;
}
Another option, however is to explicitly map the enum values to its base type, and use the base type to index into your array. For example, if you have the enum
public enum Enumerations
{
value1 = 0,
value2 = 1
}
then you can index directly into an array using myArray[(int)myEnum]. This may be of use and is the slightly-more-advanced-but-less-lines-of-code-and-arguably-easier-to-understand method.
(resisting the urge to write code)
First off, an enumeration is a named list of integers and (per MSDN) the approved types for an enum are byte, sbyte, short, ushort, int, uint, long, or ulong.
Also, remember that courseDescription is an array of strings and the purpose of the indexer is to give you an index into that array (ie. [0] returns the first string, [1] returns the second, etc.).