Other equivalent to enum? - c#

I like to use enum as value holders whereever possible and I like it. It is easy to use i.e. just put a dot and see values. It is a good replacement of hard code some time.
But still it has some limitations. We cannot put special characters in values and some other.
Actually I am trying to make code reusable. Please guide me. Is there some technique or way that I can use some data structure like enum that is flexible but have no limitations.

You could use constants; they are immutable and can have any value.
See also: http://msdn.microsoft.com/en-us/library/ms173119.aspx

If I cannot use an enum for a set of predefined values, I use a class of static constants. They look much the same in use, but the values can be anything from a decimal to a string to a struct or class. I've done this for predefined cell color schemes in GridViews, much like the built-in Color class has predefined constant values. Mathematical and scientific constants such as e and Pi (if you wanted different values than are provided by the Math class), or the acceleration of gravity (9.8m/s2), or the speed of light (299,792,458m/s), can also be specified in this way.
If you think you can't use Enums because you need to store predefined string values, try this handy trick using the System.ComponentModel Description attribute:
public Enum MyStrings
{
[Description("This is string one")] StringOne,
[Description("This is a different string")] StringTwo,
...
}
To get the strings out, you simply examine the Description attribute, the code for which is a little messy but can be easily hidden behind an extension method:
public static string GetDescription(this Enum enumValue)
{
object[] attr = enumValue.GetType().GetField(enumValue.ToString())
.GetCustomAttributes(typeof (DescriptionAttribute), false);
return (attr.Length > 0)
? ((DescriptionAttribute) attr[0]).Description
: String.Empty;
}
Usage:
var stringOne = MyStrings.StringOne.GetDescription(); //"This is string one"
In this case, you can also consider using a Resource file. The value of the string can be changed from outside the scope of the program, without a recompile.

Not sure what exactly you need (re: "special characters"), but you could simply use some constants and put them into a static class, e.g:
public static class MyConstants
{
/// <summary>documentation here</summary>
public const string ValueA = "somevalue";
/// <summary>documentation here</summary>
public const string ValueB = "something else with special characters &#";
// etc.
}
Usage:
var x = MyConstants.ValueB;

One issue you might find with enums and more especially constants is that if you change the source assembly which defines the enum or constant, but don't recompile dependent assemblies, you'll end up mismatching in the source and dependent assemblies. For example:
public const int myConst = 5;
You later change this to:
public const int myConst = 10;
In the source assembly, which was rebuilt, it's 10. But it's 5 in any dependent assemblies that were not rebuilt.
To avoid this, use readonly instead of const. For example:
public readonly int myConst = 5;
This is different than a const, which is more like a C++ #define which causes the value to be placed directly in code. Readonly will cause a lookup at runtime, so if you don't recompile your dependent assemblies you'll still get the correct, updated value.

Related

Can I assign an enum based on an array of strings?

I have a struct for a game I am building that looks like this:
using System;
public readonly struct Target
{
public Target((int Min, int Max) range, string[] targetTypes)
{
Range = range;
TargetType = ParseTypes(targetTypes);
}
public (int Min, int Max) Range { get; }
public TargetTypes TargetType { get; }
[Flags]
public enum TargetTypes { None = 0, Self = 1, Enemy = 2, Player = 4, Character = 8, Area = 16 }
}
I would like to take all of the values in the string array and cast them into a single enum (not an array of enum values, which I believe is what is happening in the answer to this question).
The thing is a Target can have multiple types. I figured an enum was the best way to represent this, and also figured defining the enum inside the struct wasn't a terrible idea, but this could be an anti-pattern (coming from a JS background, be gentle!).
I like this whole enumeration types as bit flags thing, hence the numbering, that's what sent me down this path.
Yes, I control the inputs, so happy to hear why/how I should do this differently - thanks for your time!
You could use the following.
TargetType = (TargetTypes)Enum.Parse(typeof(TargetTypes),string.Join(",",targetTypes));
The second parameter of Enum.Parse accepts either a single value/constant representing the enum or a list of named constants or underlying values delimited by commas (,).
Thank you #asawyer for pointing the way. I missed an important part of the documentation (always RFTM twice!):
Converts the string representation of the name or numeric value of one or more enumerated constants to an equivalent enumerated object.
There's no need for anything fancy here, Parse does the trick:
TargetType = (TargetTypes) Enum.Parse(typeof(TargetTypes), string.Join(",", targetTypes));

convert variable to constant

Can seems to be strange, but is there a way to declare or convert variable to constante something like :
string myVariable = "MyString";
const string myConstant = myVariable ;
I need this to answer to my problem:
linq to sql startwith performance indexed columns
thanks
no there is no way to do this for Const Const values are burned directly into the call-site at compile time, Instead you could make it readonly and assign it in the constructor
something like
string myVariable = "MyString";
readonly string myConstant="test" ;
public MyClass()
{
myConstant= myVariable ;
}
No, you cannot initialize a constant using the value of a variable.
Constants must be known at compile time, and the value of a variable is not known until runtime, making it conceptually impossible.
Otherwise, change your first variable to a constant like below :
const string myVariable = "MyString";
const string myConstant = myVariable ;
No, you can't use a variable to initialize a field. The compiler may re-arrange the order these are initialized in, myConstant could be initialized first, in which case myVariable would be not be set.
Constants cannot vary because they are not variables setting it to a variable would be varying it. So the answer is no at least not at runtime.
Maybe you just want something that can't be set many places then readonly might work.
reference: http://msdn.microsoft.com/en-us/library/acdd6hb7.aspx
public readonly string _myROString = "set once";
Well is not possible. But someone find an answer to my initial question without constant. thanks
linq to sql startwith performance indexed columns
This answer does not provide solution to the question posted; But may satisfy the requirement for some viewers who like to access string in a static manner which should be appended with other strings,
public enum NameTypes
{
First, Last
}
public static class UserDetails
{
public static string NameText = "Name Info: " + NameTypes.First.ToString();
}

Enum vs Constants/Class with Static Members?

I have a set of codes that are particular to the application (one to one mapping of the code to its name), and I've been using enums in C# to represent them. I'm not sure now if that is even necessary. The values never change, and they are always going to be associated with those labels:
Workflow_Status_Complete = 1
Workflow_Status_Stalled = 2
Workflow_Status_Progress = 3
Workflow_Status_Complete = 4
Workflow_Status_Fail = 5
Should I use an enum or a class with static members?
Static members of type int seems to be inferior to an enum to me. You lose the typesafety of an enum. And when debugging you don't see the symbolic name but just a number.
On the other hand if an entry consists of more than just a name/integervalue pair a class can be a good idea. But then the fields should be of that class and not int. Something like:
class MyFakeEnum
{
public static readonly MyFakeEnum Value1=new MyFakeEnum(...);
}
Use an enum. Even though your codes never change, it will be difficult to know what the value represents just by inspection. One of the many strengths of using enums.
enum RealEnum : uint
{
SomeValue = 0xDEADBEEF,
}
static class FakeEnum
{
public const uint SomeValue = 0xDEADBEEF;
}
var x = RealEnum.SomeValue;
var y = FakeEnum.SomeValue;
// what's the value?
var xstr = x.ToString(); // SomeValue
var ystr = y.ToString(); // 3735928559
Not even the debugger will help you much here, especially if there are many different values.
Check out the State Pattern as this is a better design. With the idea you are using you'll end up with a large switch/if-else statement which can be very difficult to keep up.
I would lean towards enums as they provide more information and they make your codes "easier to use correctly and difficult to use incorrectly". (I think the quote is from The Pragmatic Programmer.

Is it possible to implement properties in languages other than C#?

During a bout of C# and WPF recently, I got to like C#'s properties:
public double length_inches
{
get { return length_metres * 39.0; }
set { length_metres = value/39.0; }
}
Noticing, of course, that length_metres may change from being a field to a property, and the code need not care. WPF can also bind UI elements to object properties very happily.
When I first learnt about classes and objects, I assumed that there was a way to do it, because it seemed so obvious! The point of hiding complexity inside a class is that you don't need to care what is being stored any more. But it has taken until now to see it.
Amusingly, I first saw it done in VB.Net. That leading edge of OO purity.
The question is, can I recreate properties in other languages which I use more often, like javascript, python, php? In javascript, if I set a variable to a closure, won't I get the closure back again, rather than the result of it?
Python definitely supports properties:
class Foo(object):
def get_length_inches(self):
return self.length_meters * 39.0
def set_length_inches(self, val):
self.length_meters = val/39.0
length_inches = property(get_length_inches, set_length_inches)
Starting in Python 2.5, syntactic sugar exists for read-only properties, and in 2.6, writable ones as well:
class Foo(object):
# 2.5 or later
#property
def length_inches(self):
return self.length_meters * 39.0
# 2.6 or later
#length_inches.setter
def length_inches(self, val):
self.length_meters = val/39.0
In JavaScript:
var object = {
// .. other property definitions ...
get length_inches(){ return this.length_metres * 39.0; },
set length_inches(value){ this.length_metres = value/39.0; }
};
In C# properties are mostly just a compiler feature. The compiler generates special methods get_PropertyName and set_PropertyName and works out the calls and so forth. It also set the specialname IL property of the methods.
If your language of choice supports some kind of preprocessor, you can implement something similar but otherwise you're pretty much stuck with what you got.
And of course, if you're implementing your own .NET language you can do what the C# compiler does as well.
Due to the implementation details, there are actually subtle differences between fields and properties. See this question for details.
Delphi, from which C# is derived, has had properties from the word go. And the word go was about 15 years ago.
Most dynamic languages support something like that. In Smalltalk and Ruby, fields are not directly exposed - The only way to get at them is through a method. In other words - All variables are private. Ruby has some macros (class methods really), to make it simpler to type:
class Thing
attr_accessor :length_inches
end
will make a getter and a setter for length_inches. Behind the scenes, it's simply generating this:
class Thing
def length_inches
#length_inches
end
def length_inches=(value)
#length_inches = value
end
end
(Ruby crash-course: The # prefix means it's an instance variable. return is implicit in Ruby. t.length_inches = 42 will automatically invoke length_inches=(42), if t is a Thingy.)
If you later on want to put some logic in the getters/setters, you can simply manually implement the same methods:
class Thing
def length_inches
#length_metres * 39.0
end
def length_inches=(value)
#length_metres = value / 39.0
end
end
Out of the box in VB (that's VB 6.0, not VB.net) and VBScript!
Public Property Get LengthInches() As Double
LengthInches = LengthMetres * 39
End Property
Public Property Let LengthInches(Value As Double)
LengthMetres = Value / 39
End Property
Also possible to fake quite nicely in PHP creating a class that you extend in combination with naming guidelines, protected members and magic functions. Yuch.
Delphi has a property pattern (with Setter and Getter methods), which also can be used in interfaces. Properties with "published" visibility also will be displayed in the IDE object inspector.
A class definition with a property would look like this:
TFoo = class
private
FBar: string;
procedure SetBar(Value: string);
function GetBar: string;
public
property Bar: string read GetBar write SetBar;
end;
or (without Setter / Getter):
TFoo = class
private
FBar: string;
public
property Bar: string read FBar write FBar;
end;
I think this is the Python equivalent
class Length( object ):
conversion = 39.0
def __init__( self, value ):
self.set(value)
def get( self ):
return self.length_metres
def set( self, value ):
self.length_metres= value
metres= property( get, set )
def get_inches( self ):
return self.length_metres*self.conversion
def set_inches( self, value ):
self.length_metres= value/self.conversion
inches = property( get_inches, set_inches )
It works like this.
>>> l=Length(2)
>>> l.metres
2
>>> l.inches
78.0
>>> l.inches=47
>>> l.metres
1.2051282051282051
In Objective-C 2.0 / Cocoa:
#interface MyClass : NSObject
{
int myInt;
NSString *myString;
}
#property int myInt;
#property (nonatomic, copy) NSString *myString;
#end
Then in the implementation, simply specify:
#synthesize myInt, myString;
This generates the accessors for that member variable with key-value-coding compliant naming conventions like:
- (void)setMyString:(NSString *)newString
{
[myString autorelease];
myString = [newString copy];
}
Saves a lot of work typing out your accessors.
It's definitely possible to implement properties in other languages. VB and F# for example have explicit property support. But these both target the CLR which has property support.
VB.
Public Property Name As String
Get
return "someName"
End Get
Set
...
End Set
End Property
I do not believe javascript or PHP supports property syntax but I'm not very familiar with those languages. It is possible to create field get/set accessor methods in pretty much any language which simulate properties.
Under the hood, .Net properties really just result down to get/set methods. They just have a really nice wrapper :)
ActionScript 3 (javascript on steroids) has get/set syntax also
Sadly, I haven't tried it myself yet, but I read that it was possible to implement properties in PHP through __set and __get magic methods. Here's a blog post on this subject.
You can make something like it with PHP5 magic functions.
class Length {
public $metres;
public function __get($name) {
if ($name == 'inches')
return $this->metres * 39;
}
public function __set($name, $value) {
if ($name == 'inches')
$this->metres = $value/39.0;
}
}
$l = new Length;
$l->metres = 3;
echo $l->inches;
When I first played with Visual Basic (like, version 1 or something) the first thing I did was try to recreate properties in C++. Probably before templates were available to me at the time, but now it would be something like:
template <class TValue, class TOwner, class TKey>
class property
{
TOwner *owner_;
public:
property(TOwner *owner)
: owner_(owner) {}
TValue value() const
{
return owner_->get_property(TKey());
}
operator TValue() const
{
return value();
}
TValue operator=(const TValue &value)
{
owner_->set_property(TKey(), value);
return value;
}
};
class my_class
{
public:
my_class()
: first_name(this), limbs(this) {}
struct limbs_k {};
struct first_name_k {};
property<std::string, my_class, first_name_k> first_name;
property<int, my_class, limbs_k> limbs;
std::string get_property(const first_name_k &);
void set_property(const first_name_k &, const std::string &value);
int get_property(const limbs_k &);
void set_property(const limbs_k &, int value);
};
Note that the "key" parameter is ignored in the implementations of get_property/set_property - it's only there to effectively act as part of the name of the function, via overload resolution.
Now the user of my_class would be able to refer to the public members first_name and limbs in many situations as if they were raw fields, but they merely provide an alternative syntax for calling the corresponding get_property/set_property member functions.
It's not perfect, because there are some situations where you'd have to call value() on a property to get the value, whenever the compiler is unable to infer the required type conversion. Also you might get a warning from the passing of this to members in the constructor, but you could silence that in this case.
Boo is a .NET language very similar to Python, but with static typing. It can implement properties:
class MyClass:
//a field, initialized to the value 1
regularfield as int = 1 //default access level: protected
//a string field
mystringfield as string = "hello"
//a private field
private _privatefield as int
//a public field
public publicfield as int = 3
//a static field: the value is stored in one place and shared by all
//instances of this class
static public staticfield as int = 4
//a property (default access level: public)
RegularProperty as int:
get: //getter: called when you retrieve property
return regularfield
set: //setter: notice the special "value" variable
regularfield = value
ReadOnlyProperty as int:
get:
return publicfield
SetOnlyProperty as int:
set:
publicfield = value
//a field with an automatically generated property
[Property(MyAutoProperty)]
_mypropertyfield as int = 5
You could do it in all sorts of languages, with varying degrees of syntactic sugar and magic. Python, as already mentioned, provides support for this (and, using decorators you could definitely clean it up even more). PHP could provide a reasonable facsimile with appropriate __get() and __set() methods (probably some indirection to. If you're working with Perl, you could use some source filters to replicate the behaviour. Ruby already requires everything to go through.
The convention is to implement a get_PropertyName() and a set_PropertyName() method (that's all it is in the CLR as well. Properties are just syntactic sugar in VB.NET/C# - which is why a change from field to property or vice-versa is breaking and requires client code to recompile.
public int get_SomeValue() { return someValue; }
public void set_SomeValue(int value) { someValue = value; }
private int someValue = 10;
// client
int someValue = someClass.get_SomeValue();
someClass.set_SomeValue(12);

How do I access the enumerated item with an indexer and assign array string to it for display?

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.).

Categories

Resources