how to write the methods inside the enum in c# [duplicate] - c#

In Java, it's possible to have methods inside an enum.
Is there such possibility in C# or is it just a string collection and that's it?
I tried to override ToString() but it does not compile. Does someone have a simple code sample?

You can write extension methods for enum types:
enum Stuff
{
Thing1,
Thing2
}
static class StuffMethods
{
public static String GetString(this Stuff s1)
{
switch (s1)
{
case Stuff.Thing1:
return "Yeah!";
case Stuff.Thing2:
return "Okay!";
default:
return "What?!";
}
}
}
class Program
{
static void Main(string[] args)
{
Stuff thing = Stuff.Thing1;
String str = thing.GetString();
}
}

You can write an extension method for your enum:
How to: Create a New Method for an Enumeration (C# Programming Guide)

Another option is to use the Enumeration Class created by Jimmy Bogard.
Basically, you must create a class that inherits from his Enumeration. Example:
public class EmployeeType : Enumeration
{
public static readonly EmployeeType Manager
= new EmployeeType(0, "Manager");
public static readonly EmployeeType Servant
= new EmployeeType(1, "Servant");
public static readonly EmployeeType Assistant
= new EmployeeType(2, "Assistant to the Regional Manager");
private EmployeeType() { }
private EmployeeType(int value, string displayName) : base(value, displayName) { }
// Your method...
public override string ToString()
{
return $"{value} - {displayName}!";
}
}
Then you can use it like an enum, with the possibility to put methods inside it (among another things):
EmployeeType.Manager.ToString();
//0 - Manager
EmployeeType.Servant.ToString();
//1 - Servant
EmployeeType.Assistant.ToString();
//2 - Assistant to the Regional Manager
You can download it with NuGet.
Although this implementation is not native in the language, the syntax (construction and usage) is pretty close to languages that implement enums natively better than C# (Kotlin for example).

Nope. You can create a class, then add a bunch of properties to the class to somewhat emulate an enum, but thats not really the same thing.
class MyClass
{
public string MyString1 { get{ return "one";} }
public string MyString2 { get{ return "two";} }
public string MyString3 { get{ return "three";} }
public void MyMethod()
{
// do something.
}
}
A better pattern would be to put your methods in a class separate from your emum.

Since I came across, and needed the exact opposite of enum to string, here is a Generic solution:
static class EnumExtensions {
public static T GetEnum<T>(this string itemName) {
return (T) Enum.Parse(typeof(T), itemName, true);
}
}
This also ignores case and is very handy for parsing REST-Response to your enum to obtain more type safety.
Hopefully it helps someone

C# Does not allow use of methods in enumerators as it is not a class based principle, but rather an 2 dimensional array with a string and value.
Use of classes is highly discouraged by Microsoft in this case, use (data)struct(ures) instead; The STRUCT is intended as a light class for data and its handlers and can handle functions just fine. C# and its compiler don't have the tracking and efficiency capabilities as one knows from JAVA, where the more times a certain class / method is used the faster it runs and its use becomes 'anticipated'. C# simply doesn't have that, so to differentiate, use STRUCT instead of CLASS.

Related

How to make Option classes like GUILayoutOption?

I'm wondering how to make a class similar to GUILayoutOption class where it would take a whole bunch of GUILayout's static fields as parameters.
I couldn't find my answer in Unity Docs and I was wondering if somebody has made such a construct before.
I'm trying to make something like this:
public void SomeMethod( params MyClassOption[] options )
and call it for example like this: SomeMethod(MyClass.AnimationClip(aniClipRef), MyClass.AnimationDuration(duration), MyClass.StopAllOtherAnimations);
Seems like a great and clean way to wrap code with dozens of potentially optional parameters, but I'm not sure how to define it. Can somebody write a minimalistic example or explain how it works?
You won't find stuff like these in the documentation or any tutorial. If you are curious on how something is implemented, use decompiler such as .NET Reflector and you will see how each class is implemented.
Below is a minimalist example of how to do this. Do not use this. This is only here to show exactly how this is done by Unity. It uses the param keyword and performs boxing, both which allocates memory.
Example:
MyClass.Button("Submit Button", MyClass.MinWidth(10), MyClass.MaxWidth(20),
MyClass.MinHeight(10), MyClass.MaxHeight(10));
The MyClassOption class:
public class MyClassOption
{
public Type type;
public object value;
public MyClassOption(Type type, object value)
{
this.type = type;
this.value = value;
}
public enum Type
{
minWidth,
maxWidth,
minHeight,
maxHeight,
}
}
The MyClass class:
public class MyClass
{
public static bool Button(string text, params MyClassOption[] options)
{
return showButton(text, options);
}
private static bool showButton(string text, MyClassOption[] options)
{
//Not IMPLEMENTED
//DISPLAY BUTTON THEN CHECK IF IT IS CLICKED?
return false;
}
public static MyClassOption MaxHeight(float maxHeight)
{
return new MyClassOption(MyClassOption.Type.maxHeight, maxHeight);
}
public static MyClassOption MaxWidth(float maxWidth)
{
return new MyClassOption(MyClassOption.Type.maxWidth, maxWidth);
}
public static MyClassOption MinHeight(float minHeight)
{
return new MyClassOption(MyClassOption.Type.minHeight, minHeight);
}
public static MyClassOption MinWidth(float minWidth)
{
return new MyClassOption(MyClassOption.Type.minWidth, minWidth);
}
}
Basically, you add your custom options in the enum from the MyClassOption class then you add a function that will be used to access that enum in the MyClass. That function will return new MyClassOption object.
There's too much memory allocation going on each time an option is added to a function or executed to the extent that I think it is not worth it. It is fine in a normal C# application but not in a game app which can cause hiccups due to GC.
EDIT:
Things that can be done to improve this:
1.Change the MyClassOption class to struct.
2.On the MyClassOption class constructor object value parameter, change that to c# generics. T[] value.
Now, the only problem left is the param keyword which is the only thing that allocates memory. It should be fine for some applications but this is mostly useful for Editor plugins.

Adding an extension method to Property Accessor

We are doing alot of INotifyPropertyChanged implementation in our View Models and quite frankly are getting tired of having to fire the property changed events explicitly in our code for both inconvenience and aesthetic reasons.
I want to put an extension on the setter of our property, making the resulting code look like:
public string LazyAccessor
{
get;
set.notify();
}
Is there a way to do this? Can we invent one if there isn't?
Check out NotifyPropertyWeaver. This will modify your code during the build process to have your properties implement the INotifyPropertyChanged pattern.
This is available as a Visual Studio Extension
Aspect oriented programming could be solution of your problem.
See Aspect Oriented Programming in C#.
And some examples here: http://www.codeproject.com/Articles/337564/Aspect-Oriented-Programming-Using-Csharp-and-PostS
Your "set.notify()" could work with some Reflection, but I donĀ“t think this would be good solution and you will still need to implement getter and setter.
Extension methods can only be added to types. The getters and setters on automatic properties are converted into methods with backing variables by the compiler, so there is no way to put an extension method on them.
Is there a way to do this?
No, there isn't, not like you posted. Extension methods operate on types, not getters or setters.
Can we invent one if there isn't?
That would require changes to the C# specification - not a likely thing to happen.
There are other approaches that you can take to ease this - using a base class with a method that will make the boiler plate calls for you for example.
They didn't make it into 4.0, but are rumored to be included in 5.0.
I found this approach helpful.
You couldn't do it on the set itself. That is an action. You might however be able to do this:
public static class extensions()
{
public static NotifyAccessorSet(this string value) { some code }
}
public class SomeClass()
{
.....
private string mAccessor;
public string LazyAccessor{
get { return mAccessor; }
set { mAccessor = value; mAccessor.NotifyAccessorSet(); }
}
}
It's somewhat off the top of my head and keep in mind that the extension method would apply to all types string so you might want to implement your own return type and apply the extension method to it. Return that type then from lazyaccessor.
you can emulate a 'property-like' behavior without calling the event manualy by overriding the conversion operators of a custom generic struct.
The following is my solution:
public struct column<TType>
{
private TType _value;
private column(TType value) : this()
{
_value = value;
}
private void Set(TType value)
{
// Implement your custom set-behavior...
}
private TType Get()
{
// Implement your custom get-behavior...
return _value;
}
public override string ToString()
{
return _value.ToString();
}
public static implicit operator column<TType>(TType p)
{
column<TType> column = new column<TType>(p);
column.Set(p);
return column;
}
public static implicit operator TType(column<TType> p)
{
return p.Get();
}
}
I declare the struct with a generic parameter to avoid from conversion errors. You can use it like this:
public class Test
{
public column<int> kKey;
public column<float> dMoney;
public column<string> cValue;
public Test()
{
kKey = 42;
dMoney = 3.1415926f;
cValue = "May the force be with you!";
}
}
...I know, the question is outdated but it may help someone in the future.

C# Get property value without creating instance?

Is it possible to get value without creating an instance ?
I have this class:
public class MyClass
{
public string Name{ get{ return "David"; } }
public MyClass()
{
}
}
Now I need get the value "David", without creating instance of MyClass.
Real answer: no. It's an instance property, so you can only call it on an instance. You should either create an instance, or make the property static as shown in other answers.
See MSDN for more information about the difference between static and instance members.
Tongue-in-cheek but still correct answer:
Is it possible to get value without creating an instance ?
Yes, but only via some really horrible code which creates some IL passing in null as this (which you don't use in your property), using a DynamicMethod. Sample code:
// Jon Skeet explicitly disclaims any association with this horrible code.
// THIS CODE IS FOR FUN ONLY. USING IT WILL INCUR WAILING AND GNASHING OF TEETH.
using System;
using System.Reflection.Emit;
public class MyClass
{
public string Name { get{ return "David"; } }
}
class Test
{
static void Main()
{
var method = typeof(MyClass).GetProperty("Name").GetGetMethod();
var dynamicMethod = new DynamicMethod("Ugly", typeof(string),
Type.EmptyTypes);
var generator = dynamicMethod.GetILGenerator();
generator.Emit(OpCodes.Ldnull);
generator.Emit(OpCodes.Call, method);
generator.Emit(OpCodes.Ret);
var ugly = (Func<string>) dynamicMethod.CreateDelegate(
typeof(Func<string>));
Console.WriteLine(ugly());
}
}
Please don't do this. Ever. It's ghastly. It should be trampled on, cut up into little bits, set on fire, then cut up again. Fun though, isn't it? ;)
This works because it's using call instead of callvirt. Normally the C# compiler would use a callvirt call even if it's not calling a virtual member because that gets null reference checking "for free" (as far as the IL stream is concerned). A non-virtual call like this doesn't check for nullity first, it just invokes the member. If you checked this within the property call, you'd find it's null.
EDIT: As noted by Chris Sinclair, you can do it more simply using an open delegate instance:
var method = typeof(MyClass).GetProperty("Name").GetGetMethod();
var openDelegate = (Func<MyClass, string>) Delegate.CreateDelegate
(typeof(Func<MyClass, string>), method);
Console.WriteLine(openDelegate(null));
(But again, please don't!)
You can make that property static
public static string Name{ get{ return "David"; } }
Usage:
MyClass.Name;
You requirements do seem strange, but I think you're looking for some kind of metadata. You can use an attribute to achieve this:
public class NameAttribute : Attribute {
public string Name { get; private set; }
public NameAttribute(string name) {
Name = name;
}
}
[Name("George")]
public class Dad {
public string Name {
get {
return NameGetter.For(this.GetType());
}
}
}
[Name("Frank")]
public class Son : Dad {
}
public static class NameGetter {
public static string For<T>() {
return For(typeof(T));
}
public static string For(Type type) {
// add error checking ...
return ((NameAttribute)type.GetCustomAttributes(typeof(NameAttribute), false)[0]).Name;
}
}
Now this code can get names with and without instances:
Console.WriteLine(new Dad().Name);
Console.WriteLine(new Son().Name);
Console.WriteLine(NameGetter.For<Dad>());
Console.WriteLine(NameGetter.For<Son>());
You can make your property static, as pointed out by many others.
public static string Name{ get{ return "David"; } }
Be aware that this means your instances of MyClass will no longer have their own Name property, since static members belong to the class, not the individual object instances of it.
Edit:
In a note, you mentioned that you want to override the Name property in subclasses. At the same time, you want to be able to access it at the class level (access it without creating an instance of your class).
For the static properties, you would simply create a new Name property in each class. Since they are static, you're always (almost always, yay reflection) going to access them using a specific class, so you'd be specifying which version of Name you want to get. If you want to try and hack polymorphism in there and get the name from any given subclass of MyClass, you could do so using reflection, but I wouldn't recommend doing so.
Using the example from your comment:
public class Dad
{
public static string Name { get { return "George"; }
}
public class Son : Dad
{
public static string Name { get{ return "Frank"; }
}
public static void Test()
{
Console.WriteLine(Dad.Name); // prints "George"
Console.WriteLine(Son.Name); // prints "Frank"
Dad actuallyASon = new Son();
PropertyInfo nameProp = actuallyASon.GetType().GetProperty("Name");
Console.WriteLine(nameProp.GetValue(actuallyASon, null)); // prints "Frank"
}
As a side note, since you are declaring a property that has only a getter and it is returning a constant value, I recommend possibly using a const or static readonly variable instead.
public const string Name = "David";
public static readonly string Name = "David";
Usage for both would be the same:
string name = MyClass.Name;
The main benefit (and drawback) of const is that all references to it are actually replaced by its value when the code is compiled. That means it will be a little faster, but if you ever change its value, you will need to recompile ALL code that references it.
Whenever you write C# code, always check if your method and property getter/setter code does anything at all with other instance members of the class. If they don't, be sure to apply the static keyword. Certainly the case here, it trivially solves your problem.
The reason I really post to this question is that there's a bit of language bias at work in some of the answers. The C# rule that you can't call an instance method on a null object is a specific C# language rule. It is without a doubt a very wise one, it really helps to troubleshoot NullReferenceExceptions, they are raised at the call site instead of somewhere inside of a method where it gets very hard to diagnose that the this reference is null.
But this is certainly not a requirement to the CLR, nor of every language that run on the CLR. In fact, even C# doesn't enforce it consistently, you can readily bypass it in an extension method:
public static class Extensions {
public static bool IsNullOrEmpty(this string obj) {
return obj != null && obj.Length > 0;
}
}
...
string s = null;
bool empty = s.IsNullOrEmpty(); // Fine
And using your property from a language that doesn't have the same rule works fine as well. Like C++/CLI:
#include "stdafx.h"
using namespace System;
using namespace ClassLibrary1; // Add reference
int main(array<System::String ^> ^args)
{
MyClass^ obj = nullptr;
String^ name = obj->Name; // Fine
Console::WriteLine(name);
return 0;
}
Create a static property:
public class MyClass
{
public static string Name { get { return "David"; } }
public MyClass()
{
}
}
Get it like so:
string name1 = MyClass.Name;
That is not possible. As Name is an instance property, you can only get its value if you have an instance.
Also, note that you are not talking about a parameter, but about a property.
Create a static class or a static property, and you don't have to explicitly instantiate it.

Creating a Generic Class Member for Extra Info

I'm very new to C# (this is my first C# project). I'm fairly confident with the basics, but I'm starting to run into things that are raising issues that I can't quite solve, no matter how many different ways I Google it. A LOT of my questions have been answered by this site. :]
So, since I can't find the answer to this question, I decided to post it myself.
Maybe it's too basic of a question that everyone pretty much knows it, but I couldn't figure this out from the MSDN reading.
It has to do with C# Generics. I'm programming for a video game engine, and I've created a simple messaging system between AI units. The Message class contains members like sender, receiver, dispatchTime, and extraInfo. I want to use the extraInfo member to be a useful, flexible addition to the Message class, so I would like for it to be able to contain any type (an int node index, a double path cost, a relevant Vector3 position from XNA, etc, etc...). My research for this pointed me in the direction of Generics.
I figured out how to use Generics in something like a List, but I haven't read anything about how to just declare and implement a generic -member-. Just a single member, not a collection.
How would I declare this member, extraInfo? Additionally, when accessing it from another class, I would like to be able to type:
info = message.extraInfo;
..to retrieve the extra information via the get property.
How would this be done in C#?
Your message class would look something like this
public class Message<T>
{
public object Sender { get; set; }
public object Receiver { get; set; }
public T ExtraInfo { get; set; }
}
public static void Main()
{
Message<double> doubleMessage = new Message<double>() { ExtraInfo = 4.0d };
Message<string> stringMessage = new Message<string>() { ExtraInfo = "Hello World" };
}
Using .NET 4.0, you can make your ExtraInfo property of type dynamic. You could then store anything at all in it, and as long as you access it properly at runtime, you'll be ok.
You could declare the extraInfo member of your class as an object. You could then put anything you want in there.
You can solve your problem by creating an ExtraInfoType object that contains an
object as well as implicit operators to convert to and from the various object types transparently.
The ExtraInfoType object can also indicate what kind of object is stored in the ExtraInfoType.
An example of this implementation is below.
enum ExtraInfoKind
{
Integer,
Double
}
class ExtraInfoType
{
object value;
public object Value {
get { return value; }
}
ExtraInfoKind kind;
public ExtraInfoKind Kind {
get { return kind; }
}
private ExtraInfoType(object o, ExtraInfoKind kind){
this.value=o;
this.kind=kind;
}
public static implicit operator int(ExtraInfoType o){
if(o.kind!= ExtraInfoKind.Integer)
throw new InvalidCastException();
return (int)o.value;
}
public static implicit operator double(ExtraInfoType o){
if(o.kind!= ExtraInfoKind.Double)
throw new InvalidCastException();
return (double)o.value;
}
public static implicit operator ExtraInfoType(int o){
return new ExtraInfoType(o, ExtraInfoKind.Integer);
}
public static implicit operator ExtraInfoType(double o){
return new ExtraInfoType(o, ExtraInfoKind.Double);
}
}
/* Example
class Program
{
public static void Main(string[] args)
{
ExtraInfoType t=1;
Console.WriteLine(t.Kind);
int valueT=t;
Console.WriteLine(t);
Console.ReadLine();
}
}
*/
Here you would declare extraInfo under the type ExtraInfoType.
Note that no generics are necessary here. Note also that ExtraInfoType
can store only one kind of object, which can be determined by the Kind property.
If the object is cast to the wrong type, an InvalidCastException is thrown, as
can be seen in the implicit operators above.

Can I pass parameters by reference in Java?

I'd like semantics similar to C#'s ref keyword.
Java is confusing because everything is passed by value. However for a parameter of reference type (i.e. not a parameter of primitive type) it is the reference itself which is passed by value, hence it appears to be pass-by-reference (and people often claim that it is). This is not the case, as shown by the following:
Object o = "Hello";
mutate(o)
System.out.println(o);
private void mutate(Object o) { o = "Goodbye"; } //NOT THE SAME o!
Will print Hello to the console. The options if you wanted the above code to print Goodbye are to use an explicit reference as follows:
AtomicReference<Object> ref = new AtomicReference<Object>("Hello");
mutate(ref);
System.out.println(ref.get()); //Goodbye!
private void mutate(AtomicReference<Object> ref) { ref.set("Goodbye"); }
Can I pass parameters by reference in
Java?
No.
Why ? Java has only one mode of passing arguments to methods: by value.
Note:
For primitives this is easy to understand: you get a copy of the value.
For all other you get a copy of the reference and this is called also passing by value.
It is all in this picture:
In Java there is nothing at language level similar to ref. In Java there is only passing by value semantic
For the sake of curiosity you can implement a ref-like semantic in Java simply wrapping your objects in a mutable class:
public class Ref<T> {
private T value;
public Ref(T value) {
this.value = value;
}
public T get() {
return value;
}
public void set(T anotherValue) {
value = anotherValue;
}
#Override
public String toString() {
return value.toString();
}
#Override
public boolean equals(Object obj) {
return value.equals(obj);
}
#Override
public int hashCode() {
return value.hashCode();
}
}
testcase:
public void changeRef(Ref<String> ref) {
ref.set("bbb");
}
// ...
Ref<String> ref = new Ref<String>("aaa");
changeRef(ref);
System.out.println(ref); // prints "bbb"
From James Gosling in "The Java Programming Language":
"...There is exactly one parameter passing mode in Java - pass by value - and that keeps things simple.
.."
I don't think you can. Your best option might be to encapsulate the thing you want to pass "by ref" onto another class instance, and pass the (outer) class's reference (by value). If you see what I mean...
i.e. your method changes the internal state of the object it is passed, which is then visible to the caller.
Java is always pass by value.
When you pass a primitive it's a copy of the value, when you pass an object it's a copy of the reference pointer.
Another option is to use an array, e.g.
void method(SomeClass[] v) { v[0] = ...; }
but 1) the array must be initialized before method invoked, 2) still one cannot implement e.g. swap method in this way...
This way is used in JDK, e.g. in java.util.concurrent.atomic.AtomicMarkableReference.get(boolean[]).
Check out my response in: http://stackoverflow.com/a/9324155/1676736
In there I used a simpler version of the wrapper class idea.
I don't like setters/getters as a standard. When there is no reason to bury a field I make it 'public'. Especially in something like this.
However, this would work for all but the primitive, or multi-parameter/type returns:
public class Ref<T> {
public T val;
}
Although, I suppose you could just add more type parameters. But I think that creating an inner static class fit-for-purpose would be easier:
public static class MyReturn {
public String name;
public int age;
public double salary;
}
this would be for use when you don't need it for other reasons.
MyReturn mRtn = new MyReturn();
public void myMethod(final MyReturn mRtn){
mRtn.name = "Fred Smith";
mRtn.age = 32;
mRtn.salary = 100000.00;
}
System.out.println(mRtn.name + " " +mRtn.age + ": $" + mRtn.salary);

Categories

Resources