idea to create rich enum - c#

I have created for myself several classes of the same structure - "rich enums". So it immediately suggests that it could be somehow simplified by another class I would inherit.
I wrote an example class to show you what such an enum contains:
class RichEnum
{
// ???
}
class MyEnum : RichEnum
{
// FIELDS AND CONSTRUCTOR(S)
public readonly string A;
public readonly int B;
public readonly Object C;
public MyEnum(string A, int B, Object C)
{
this.A = A;
this.B = B;
this.C = C;
}
// STATIC INSTANCES
public static readonly MyEnum Example1 = new MyEnum("string1", 1, "object1");
public static readonly MyEnum Example2 = new MyEnum("string2", 2, "object2");
public static readonly MyEnum Example3 = new MyEnum("string3", 3, "object3");
// SPECIAL INSTANCE
public static readonly MyEnum Default = new MyEnum("default", 0, "default");
// SPECIAL OBJECT FOR ITERATING OVER STATIC INSTANCES
public static readonly MyEnum[] Values = { Example1, Example2, Example3 };
// METHODS
public int GetSomeNumber()
{
return B + 10;
}
}
I have lots of various "MyEnums", but these classes all have the same structure. So they have:
Some public readonly fields (variable number) of various types
One or more constructors
Public static readonly instances
A special field used to return the value if none of those instances can match a condition. For example when I use MyEnum.Values.FirstOrDefault(...), that would return default when nothing is found
Some methods
Is there a way to create one class of this structure and then just inherit from it, making the process more simplified and less error-prone?

It seems you're reinventing the wheel: Headspring.Enumeration.
So, if your goal is just to have such a "rich" enumeration class available to you, there's a Nuget package for that; if your goal is to write your own ... well, it never hurts to look at prior art for inspiration.

If you really look at it, these classes have actually nothing in common that could be abstracted:
They have a different amount of static and non-static fields
The types of the fields are different
The values of each field differ
The names of the fields differ
The methods differ
Unless you find something they have in common, you can't create a base class. What could help you would be a code snippet that contains the general layout of such a class to speed up your typing.

Take a look at this code I posted on CodeProject a LONG time ago.
http://www.codeproject.com/Articles/13293/Descriptive-Enumerations
I won't post all the code, although it's not too bad, but here's an example of actually using it. In this case, I am trying to define an enum of a passenger's airline seat preference.
public class SeatType : DescriptiveEnum<SeatType, int>
{
public static readonly SeatType Window = new SeatType("Window Seat", 1);
public static readonly SeatType Aisle = new SeatType("Aisle Seat", 2);
public static readonly SeatType AnythingExceptSeatNearBathroom = new SeatType("Anything Except Seat Near Bathroom", 3);
private SeatType(string desc, int code)
: base(desc, code)
{
}
}
So, as you can see, that's pretty clean. Of course, you could certainly extend this to add additional methods, or include a "default", etc.
Then you can use it like this:
class Example
{
public static void Main(string[] args)
{
SeatType c = SeatType.AnythingExceptSeatNearBathroom;
Console.WriteLine(c.Description);
Console.WriteLine(SeatType.AnythingExceptSeatNearBathroom == c);
foreach (SeatType seat in SeatType.GetEnumMembers())
{
Console.WriteLine(String.Format("Seat type code: {0} - description: {1}",seat.Code,seat.Description));
}
Console.ReadLine();
}
}
The base DescriptiveEnum class also has conversion operators baked in, so it works JUST like enums do. That is, you can say:
SeatType c = (SeatType) SomeMethodThatReturnsAnInt();

Related

C# anonymous value types nature

Consider the flowing code snippet
static void Main()
{
var x = new MyStruct
{
Item = new StringWrapper("abc")
};
Console.WriteLine(x.Item.PublicField);
x.Item.SetValue("xyz");
Console.WriteLine(x.Item.PublicField);
var y = new
{
Item = new StringWrapper("abc")
};
Console.WriteLine(y.Item.PublicField);
y.Item.SetValue("xyz");
Console.WriteLine(y.Item.PublicField);
}
public struct MyStruct
{
public StringWrapper Item;
}
public struct StringWrapper
{
public string PublicField;
public StringWrapper(string v)
{
PublicField = v;
}
public void SetValue(string v)
{
PublicField = v;
}
}
And the output:
abc
xyz
abc
abc
MyStruct can be declared as class, and the output will remain the same.
{abc, abc} part of output is a surprise for me, as I expect anonymous type to be converted to class or struct and behave the same.
I feel like I'm missing something obvious here and will appreciate any help.
Thanks.
The difference here is that your MyStruct (struct or class) exposes a public field while anonymous classes (new { }) expose public properties.
When you access a value type from a field or variable, you do not get a copy, you access the instance directly. Therefore making changes to it stores them in the instance.
When you instead access it via a property or method, you get a returned copy of your StringWrapper and changing that doesn't change what is stored in the anonymous classes private field.
Just to demonstrate, you can get the same behavior by making your Item field a property too:
public StringWrapper Item { get; set; }

What is the use of "this" in Java and/or C#? [duplicate]

This question already has answers here:
When do you use the "this" keyword? [closed]
(31 answers)
Closed 9 years ago.
Say I have a simple sample console program like below. My question is in regards to this. Is the sole use of this just so you can use the input variable name to assign to the instance variable? I was wondering what the use of this is other than used in the context of this program?
public class SimpleClass {
int numberOfStudents;
public SimpleClass(){
numberOfStudents = 0;
}
public void setStudent(int numberOfStudents){
this.numberOfStudents = numberOfStudents;
}
public void printStudents(){
System.out.println(numberOfStudents);
}
public static void main(String[] args) {
SimpleClass newRandom = new SimpleClass();
newRandom.setStudent(5);
newRandom.printStudents();
}
}
Previously, when I needed to assign a value to an instance variable name that shares similarities to the input value, I had to get creative with my naming scheme (or lack of). For example, the setStudent() method would look like this:
public void setStudent(int numberOfStudentsI){
numberOfStudents = numberOfStudentsI;
}
From that example above, it seems like using this replaces having to do that. Is that its intended use, or am I missing something?
Things are quite the opposite of how you perceive them at the moment: this is such an important and frequently used item in Java/C# that there are many special syntactical rules on where it is allowed to be assumed. These rules result in you actually seeing this written out quite rarely.
However, except for your example, there are many other cases where an explicit this cannot be avoided (Java):
referring to the enclosing instance from an inner class;
explicitly parameterizing a call to a generic method;
passing this as an argument to other methods;
returning this from a method (a regular occurrence with the Builder pattern);
assigning this to a variable;
... and more.
this is also used if you want to a reference to the object itself:
someMethod(this);
There is no alternative to this syntax (pun intended).
It's also used to call co-constructors, and for C# extension methods.
'this' simply refers to the object itself.
When the compilers looks for the value of 'numberOfStudents', it matches the 'closest' variable with this name. In this case the argument of the function.
But if you want to assign it to the class variable, you need to use the 'this.'-notation!
In the method
public void setStudent(int numberOfStudents){
this.numberOfStudents = numberOfStudents;
}
for example.
'this.numberOfStudents' references the class variable with the name 'numberOfStudents'
'numberOfStudents' references the argument of the method
So, this method simple assigns the value of the parameter to the class variable (with the same name).
in c# you use this to refer the current instance of the class object immagine you have class like this from msdn
class Employee
{
private string name;
private string alias;
private decimal salary = 3000.00m;
// Constructor:
public Employee(string name, string alias)
{
// Use this to qualify the fields, name and alias:
this.name = name;
this.alias = alias;
}
// Printing method:
public void printEmployee()
{
Console.WriteLine("Name: {0}\nAlias: {1}", name, alias);
// Passing the object to the CalcTax method by using this:
Console.WriteLine("Taxes: {0:C}", Tax.CalcTax(this));
}
public decimal Salary
{
get { return salary; }
}
}
class Tax
{
public static decimal CalcTax(Employee E)
{
return 0.08m * E.Salary;
}
}
class MainClass
{
static void Main()
{
// Create objects:
Employee E1 = new Employee("Mingda Pan", "mpan");
// Display results:
E1.printEmployee();
}
}
/*
Output:
Name: Mingda Pan
Alias: mpan
Taxes: $240.00
*/
You have different scopes of variables in Java/C#. Take this example below. Although this.numberOfStudents and numberOfStudents have the same name they are not identical.
public void setStudent(int numberOfStudents){
this.numberOfStudents = numberOfStudents;
}
this.numberOfStudents is a variable called numberOfStudents that is in the instance of this class. this always points on the current instance.
public void setStudent(int numberOfStudents) that numberOfStudents is a new variable that is just available in this method.
keyword "this" refers to an object of the current class (SimpleClass) on the fly.
public class SimpleClass(){
private int a;
private int b;
private int c;
public SimpleClass(int a, int b){
this.a = a;
this.b = b;
}
public SimpleClass(int a, int b, int c){
// this constrcutor
this(a,b);
this.c = c;
}
}

Creating a non-static version of compiler-based "dictionary" where keys are types

There is a very easy trick which creates a dictionary-like structure where keys are types.
The structure acts like a Dictionary<Type, T?> where keys are Type objects and values are instances of the corresponding types.
This wonderful structure is as fast as just a variable or array since the "lookup" is only done once by the compiler/JITter and the proper value reference is compiled into your program.
public static class MyDict<T> {
public static T Value { get; set; }
}
You can work with that structure like this:
MyDict<string>.Value = MyDict<int>.Value.ToString();
The problem is that this "dictionary" is global. The only way to create different dictionaries is to create different classes.
How can create a similar (fastest "lookup", no boxing) non-static structure? (Without code generation.)
Simply said: I want to have multiple Dictionary<Type, object>-like objects without lookup costs, casting and boxing.
Here's an approach that extends the method described in the question:
public class TypeDict
{
public T Get<T>()
{
return MyDict<T>.Values[this];
}
public void Set<T>(T value)
{
MyDict<T>.Values[this] = value;
}
private static class MyDict<T>
{
public static Dictionary<TypeDict, T> Values { get; private set; }
static MyDict()
{
Values = new Dictionary<TypeDict, T>();
}
}
}
Now we can use the TypeDict like this:
void X()
{
var a = new TypeDict();
var b = new TypeDict();
a.Set<int>(1);
a.Set<double>(3.14);
a.Set("Hello, world!");
//Note that type inference allows us to omit the type argument
b.Set(10);
b.Set(31.4);
b.Set("Hello, world, times ten!");
Console.WriteLine(a.Get<int>());
Console.WriteLine(a.Get<double>());
Console.WriteLine(a.Get<string>());
Console.WriteLine();
Console.WriteLine(b.Get<int>());
Console.WriteLine(b.Get<double>());
Console.WriteLine(b.Get<string>());
}
Ark-kun is using generics to essentially generate unique types at compile time. With a generic type, any static members are unique to that specific closed generic type. This way it's processed as fast as a standard static member lookup.
The above usage is equivalent to something like this:
public static class MyDict_String
{
public static string Value { get; set; }
}
public static class MyDict_Int32
{
public static int Value { get; set; }
}
MyDict_String.Value = MyDict_Int32.Value.ToString();
AFAIK, types are "static" (in that you can't define more than one that way) so I don't know of a way to cheat around this and maintain the same performance of a statically compiled member lookup.
Your best bet otherwise (I think) is to create a generic instance type that wraps its own dictionary that uses System.Type for its keys and System.Object for its values to which you have to perform boxing/casting when inserting/retrieving values.
EDIT: Here's a simple implementation wrapping a dictionary:
public class MyTypedDict
{
private Dictionary<Type, object> Values = new Dictionary<Type, object>();
public T Get<T>()
{
object untypedValue;
if (Values.TryGetValue(typeof(T), out untypedValue))
return (T)untypedValue;
return default(T);
}
public void Set<T>(T value)
{
Values[typeof(T)] = value;
}
}
Thinking about it more, it might be possible to achieve a more property-like syntax using an ExpandoObject (http://msdn.microsoft.com/en-us/library/system.dynamic.expandoobject.aspx) through some tomfoolery, but I feel like this would be pretty abusive and I can only assume terribly prone to runtime errors. (plus it would afford you nothing at compile time)
EDITx2: If you really want to have different sets of values, you could nest it within another generic type:
public static class ValueSets<T>
{
public static class MyDict<U>
{
public static U Value { get; set; }
}
}
With usage like:
ValueSets<int>.MyDict<string>.Value = "Hello ";
ValueSets<bool>.MyDict<string>.Value = "World!";
string helloworld = ValueSets<int>.MyDict<string>.Value + ValueSets<bool>.MyDict<string>.Value;
Console.WriteLine(helloworld);//Hello World!
But then the initial type int and bool in this case become "magical" and without meaning, plus you would need to provide a unique type per distinct set of values you'd like to use. Plus you could not pass it around and modify as an instance variable, rather it'd be statically accessible (so long as you have access to use the type T). So perhaps you could declare minimally visible types that are named with meaning and use those:
internal class MyFirstWords {}
internal class MySecondWords {}
ValueSets<MyFirstWords>.MyDict<string>.Value = "Hello ";
ValueSets<MySecondWords>.MyDict<string>.Value = "World!";
string helloworld = ValueSets<MyFirstWords>.MyDict<string>.Value + ValueSets<MySecondWords>.MyDict<string>.Value;
Console.WriteLine(helloworld);//Hello World!
Regardless, I think this is quite wacky and I wouldn't recommend it.
A more complicated version. Don't know if it's closer:
Define a generic dictionary:
public class MyDictionary<T>
{
Dictionary<string, T> dict;
public MyDictionary()
{
dict = new Dictionary<string, T>();
}
public T this[string name]
{
get
{
if (dict.ContainsKey(name))
return dict[name];
else
return default(T);//or throw
}
set
{
dict[name] = value;
}
}
}
Then a repository to store those dictionaries:
public class MyRepository
{
List<object> repo;
public MyRepository()
{
repo = new List<object>();
}
public void Add<T>(string name, T value)
{
if (!repo.OfType<MyDictionary<T>>().Any())
repo.Add(new MyDictionary<T>());
var dict = repo.OfType<MyDictionary<T>>().FirstOrDefault();
dict[name] = value;
}
public T GetValue<T>(string name)
{
if (!repo.OfType<MyDictionary<T>>().Any())
return default(T);//or throw
else
{
var dict = repo.OfType<MyDictionary<T>>().FirstOrDefault();
return dict[name];
}
}
}
And finally you may use this repository:
MyRepository repo = new MyRepository();
repo.Add("A", 1);
repo.Add("B", 1);
int i = repo.GetValue<int>("A") + repo.GetValue<int>("B");
In this example, there is MyDictionary<T> boxing to object is left.
From the other side, if your are working with some certain types you may not use thie repository class at all. But utilize separate dictionaties.
MyDictionary<int> intDict = new MyDictionary<int>();
intDict["A"] = 1;
intDict["B"] = 2;
int i = intDict["A"] + intDict["B"];
However it's the same as working with
Dictionary<string, int> intDict = new Dictionary<string, int>();
So the MyRepository class may be edited to use Dictionary<string, T> instead of MyDictionary<T>.
#Konstantin's answer made me remember that there is actually a very fast lookup method - array indexing. This crude PoC code shows a variant of the required structure.
public class TypeDictionary {
static int _maxId = 0;
int _id;
static class Store<T>{
internal static List<T> Values = new List<T>();
}
public TypeDictionary() {
_id = _maxId++;
}
public T GetValue<T>() {
return Store<T>.Values[_id];
}
public void SetValue<T>(T value) {
while(Store<T>.Values.Count < _id) {
Store<T>.Values.Add(default(T));
}
Store<T>.Values[_id] = value;
}
}
This code can be used as follows:
var dict1 = new TypeDictionary();
dict1.SetValue("my string");
string result = dict1.GetValue<string>();
The problem with this solution is it's memory usage caused by the repository being not sparse. This also makes first time value setting more expensive.
Try this:
public class MyDictionary
{
List<object> values;
public MyDictionary()
{
values = new List<object>();
}
public T GetValue<T>()
{
return values.OfType<T>().FirstOrDefault();
}
public bool Add<T>(T value)
{
if (values.OfType<T>().Any())
return false;
else
{
values.Add(value);
return true;
}
}
}
and use it:
var md = new MyDictionary();
md.Add("!!!");
string s = md.GetValue<string>();
This class may store up to one value of type T. But there could corner cases with derived classes and interfaces I guess. You may check, if it suits your need, and probably modify it as you need, if it's close to what you need in general.
What you are looking for is impossible in C#. The language does not support a container that could store multiple objects of different types yet provides a look up method that does not involve casting, boxing or unboxing. You could accomplish something like this with macros in C++, or via a language like javascript where the structure of types can be changed at run-time.
The usage case you are describing fits quite closely with the purpose for which ConditionalWeakTable<TKey,TValue> was added to .NET 4.0. For the purpose you describe, you would include such a table in a static generic class, and then for every class object that's supposed to contain a reference to an item of a particular type you would store into that type's table a reference to object that's supposed to contain the item along with either a reference to the item, or else a reference to a simple item-holder object (note that entries in ConditionalWeakTable will evaporate when an object ceases to exist, but are otherwise immutable, so if you want a mutable association you'll need to create an object to hold it).
Building on #phoog's example with #supercat's suggestion
public class TypeDict
{
public T Get<T>() where T : class
{
T value;
InnerDict<T>.Values.TryGetValue(this, out value);
return value;
}
public void Set<T>(T value) where T : class
{
var cwt = InnerDict<T>.Values;
// lock+remove+add https://github.com/dotnet/coreclr/issues/4545
lock (cwt)
{
cwt.Remove(this);
cwt.Add(this, value);
}
}
private static class InnerDict<T> where T : class
{
public static ConditionalWeakTable<TypeDict, T> Values { get; private set; }
static InnerDict()
{
Values = new ConditionalWeakTable<TypeDict, T>();
}
}
}

C# Language Enum Declaration

Hi Is there a way to declare an enum or to customize the way of declaring an enum which returns an object in C#?
private enum testEnum
{
firstname =1
,lastname = 2
}
and if we want to return the names rather than 1 and 2 ?
like testEnum.firstname returns 1 .
I want to declare an enum to return objects like in Java . is it possible?
You can do this:
public class NameEnum
{
static NameEnum()
{
FirstName = new NameEnum("FirstName");
LastName = new NameEnum("LastName");
}
public static NameEnum FirstName { get; private set; }
public static NameEnum LastName { get; private set; }
private NameEnum(string name)
{
this.Name = name;
}
public string Name { get; private set; }
}
Is that close enough?
http://msdn.microsoft.com/de-de/library/system.enum.aspx
An enumeration is a set of named constants whose underlying type is any integral type except Char. If no underlying type is explicitly declared, Int32 is used. Enum is the base class for all enumerations in the .NET Framework.
You can use interfaces for this:
interface IColorEnum {};
class ColorEnum: IColorEnum
{
public static const Red = new ColorEnum();
public static const Green = new ColorEnum();
public static const Blue = new ColorEnum();
};
And use it like usual:
void foo(IColorEnum color)
{
if(color == ColorEnum.Red) {...}
}
Update+improve: you can even drop interface and just use class with couple of public static fields with type of this class and private constructor to prevent creating new instances of it:
class ColorEnum
{
private ColorEnum() {};
public static const Red = new ColorEnum();
public static const Green = new ColorEnum();
public static const Blue = new ColorEnum();
};
The docs state:
Every enumeration type has an underlying type, which can be any integral type except char.
Assuming you mean object to be complex/reference type. then the answer to your question is no. You could always create a class with named properties containing reference types.
I guess that you be a class exposing static fields that can then be of any type you want.
I think this is only possible in java.
It seems that you want to implement singleton the Joshua Bloch way.

C# compiler error: "cannot have instance field initializers in structs"

I need advice on structures.
I have 2 sections of code. The first section is as below:
namespace Project.GlobalVariables
{
class IOCard
{
struct InputCard
{
public string CardNo;
public int BaseAddress;
public int LowerAddress;
public int UpperAddress;
public int[] WriteBitNo = new int[16];
public int[] ReadBitNo = new int[16];
}
static InputCard[] InputCards = new InputCard[5];
public static string ACardNo = InputCards[1].CardNo;
public static string BCardNo = InputCards[2].CardNo;
}
}
The second portion is as below:
private void Form1_Load(object sender, EventArgs e)
{
IOCard.ACardNo = "Card A";
IOCard.BCardNo = "Card B";
MessageBox.Show(IOCard.ACardNo);
MessageBox.Show(IOCard.BCardNo);
}
My plan is to be able to assign and retrieve InputCards component by using IOCard as shown in Form1_Load.
However, when I compile the code, I get the following error.
Error 1 'Project.GlobalVariables.IOCard.InputCard.WriteBitNo': cannot have instance field initializers in structs E:\Programming\New platform\StandardPlatform\StandardPlatform\Project\GlobalVariables.cs 16 26 StandardPlatform
Can someone tell me how to solve the error?
Please advise. Thanks.
Here are the classes that I have attempted to create and use, but failed.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Project.GlobalVariables
{
static class IOCard
{
public const int TotalInputCard = 10;
public const int TotalOutputCard = 10;
public class InputCard
{
public string CardNo = "1";
public int BaseAddress;
public int LowerAddress;
public int UpperAddress;
public int[] WriteBitNo = new int[16];
public int[] ReadBitNo = new int[16];
}
public class OutputCard
{
public string CardNo;
public int BaseAddress;
public int LowerAddress;
public int UpperAddress;
public int[] WriteBitNo = new int[16];
public int[] ReadBitNo = new int[16];
}
public static InputCard[] InputCards = new InputCard[TotalInputCard];
public static OutputCard[] OutputCards = new OutputCard[TotalOutputCard];
public static int X100 = InputCards[0].WriteBitNo[0];
public static int Y100 = OutputCards[0].WriteBitNo[0];
}
}
I tried to use these in the Form_Load, like so:
private void Form1_Load(object sender, EventArgs e)
{
IOCard.X100 = 1;
IOCard.Y100 = 1;
}
No matter how much I have tried to search on the net for answers, I have got nowhere.
Please advise. Thanks.
In C#, a struct value is not a reference to an object in the way a value of a class type is. The value of a struct is the "union" of all the values of the instance fields of the struct.
Now, the default value of a struct type is the value where all those fields have their default values. Since the beginning of C#, the syntax:
new S() // S is a value-type
where S is a struct type, has been equivalent to the default value of that struct. There is no constructor call! This is the exact same value which can (nowadays) also be written
default(S) // S is a value-type
Now, things like
struct S
{
int field = 42; // non-static field with initializer, disallowed!
// ...
}
are illegal (cannot have instance field initializers in structs). They could give the impression that the field of a new S() would be 42, but in fact the field of new S() must be the default value of int (which is zero, distinct from 42).
With this explanation, you also see why it is not possible to create a non-static, zero-parameter constructor for a struct type, in C#.
What's it's trying to say is that when you have InputCards = new InputCard[5]; it will allocate a block of memory 5 times the size of an InputCard structure and set all of its bytes to 0. There is no opportunity to execute the int[] WriteBitNo = new int[16]; and such assignments, so you cannot have them.
Your options are to either manually call an initializer for your structs or make it a class and manually initialize the InputCards array with 5 new instances of InputCard.
You will neither be able to initialize a struct's fields nor define a default constructor to initialize it's fields. After looking at your struct, I recommend you use a class instead. It's not recommended to use a struct for a scenario where you have a bunch of fields.
Try this. Initialize the InputCard with a factory function Create():
namespace Project.GlobalVariables
{
class IOCard
{
struct InputCard
{
public string CardNo;
public int BaseAddress;
public int LowerAddress;
public int UpperAddress;
public int[] WriteBitNo;
public int[] ReadBitNo;
static InputCard Create()
{
return new InputCard()
{
CardNo = string.Empty,
WriteBitNo = new int[16],
ReadBitNo = new int[16]
};
}
}
static InputCard[] InputCards = new InputCard[]
{
InputCard.Create(),
InputCard.Create(),
InputCard.Create(),
InputCard.Create(),
InputCard.Create()
};
public static string ACardNo = InputCards[1].CardNo;
public static string BCardNo = InputCards[2].CardNo;
}
}
Use class instead of structure. Structure is used for small types like Point, which are faster to create on the stack and copy, than to create dynamically and pass by reference.
Not sure about the exception, but i have a solution.
You should not use "struct" for this class, it is too much (and storing too much data). If you define it as "class", the same code would work fine.
Is there a particular reason why you want this to be a struct rather than a class?
If you make it a class, it works just fine.

Categories