C# enum to string auto-conversion? - c#

Is it possible to have the compiler automatically convert my Enum values to strings so I can avoid explicitly calling the ToString method every time. Here's an example of what I'd like to do:
enum Rank { A, B, C }
Rank myRank = Rank.A;
string myString = Rank.A; // Error: Cannot implicitly convert type 'Rank' to 'string'
string myString2 = Rank.A.ToString(); // OK: but is extra work

No. An enum is its own type, so if you want to convert it to something else, you have to do some work.
However, depending on what you're doing with it, some methods will call ToString() on it automatically for you. For example, you can do:
Console.Writeline(Rank.A);

You are not probably looking for enums itself, but a list of string constant. It can fit your needs better in some scenarios.
Use this instead:
public static class Rank
{
public const string A = "A";
public const string B = "B";
public const string C = "C";
}

No, but at least you can do things with enums that will call their ToString() methods when you might need to use their string value, e.g.:
Console.WriteLine(Rank.A); //prints "A".

The correct syntax should be
myRank.ToString("F");

[Caution, hack] Unsure as to whether this is nasty, to me it seems a reasonable compromise.
var myEnumAsString = MyEnum+"";
Console.WriteLine(myEnumAsString); //MyEnum
This will force implicit ToString()

Related

Know if a type can be converted to string representing the data [duplicate]

I am writing an interop between a php service and our crm. One of the things I need to do is make sure that simple types get converted ToString() for use later in a json converter.
I am not sure even what the name is for 'simple types' but it can be defined like this... "an object that represents a low level variable type, containing a single value, not a class or anything with executable functions etc"
I've found that int, string, bool, double, and surprisingly enum will ToString() with pretty predictable results.
int x = 0;
bool y = true;
double z = 1.59 // money
CustomEnum theEnum = CustomEnum.somevalue;
x.ToString() results in "0"
y.ToString() results in "true"
z.ToString() results in "1.59"
theEnum.ToString() results in "somevalue"
But if I use this:
List<int> iList = new List<int>();
iList.Add(1);
MyClass theClass = new MyClass();
iList.ToString() results in "System.Collections.Generic.List`1[System.Int32]"
theClass.ToString() results in "STTI.NKI.Interop.MyClass"
I'm not limited to lists. I could have an ExpandoObject, or a class etc.
I understand EXACTLY why this happens, and I want to know if there is a quick way to determine if an object of unknown type will ToString() into an expected value, and not the type name. I find it an antipattern to do something like
switch (theObject.GetType())
case typeof(int):
case typeof(bool):
case typeof(doulble):
etc
I am not sure what the terms are, so googling my answer is proving difficult.
So you want to check whether a type has a overridden ToString method? Why not just check whether the value returned by ToString is equal to the value returned by the default implementation of ToString?
From here, we know the default implementation of ToString is
return GetType().ToString();
So, we can use this to check whether an object has overridden the ToString method:
bool toStringOverridden = someObject.GetType().ToString() !=
someObject.ToString();
The ToString method is a virtual one and the default implementation is defined in the Object class and simply returns the name of the type of the object:
public virtual string ToString()
{
return this.GetType().ToString();
}
int for example, overrides this method to return a meaningful representation.
What you can do is use reflection to detect whether a type overrides the ToString method like this:
public static bool OverridesToString(Type type)
{
return type.GetMethod("ToString", new Type[0]).DeclaringType != typeof(object);
}
If it does, there is a very good chance that the ToString method would return something meaningful.
Option 1: make sure that every Object will overwrite ToString().
Option 2: Use reflection to get all object properties and concat them.
Maybe you can do something similar to this:
bool ToStringIsTyped<T>(T myObj)
{
return myObj.ToString().Contains(typeof(T).FullName);
}
It may not work in all cases, but possibly could be expanded
I Think this is what you are looking, in the GetMethod the second argument is an empty array to watch for the .ToString(), just convert the i.GetType().GetMethod("ToString", new Type[] { }).DeclaringType == typeof(object) to a function and there you go.
class Program
{
static void Main(string[] args)
{
int i = 55;
var s = "some string";
var x = new List<string>();
Console.WriteLine(i.ToString());
Console.WriteLine(i.GetType().GetMethod("ToString", new Type[] { }).DeclaringType == typeof(object));
Console.WriteLine(s.ToString());
Console.WriteLine(s.GetType().GetMethod("ToString",new Type[]{}).DeclaringType == typeof(object));
Console.WriteLine(x.ToString());
Console.WriteLine(x.GetType().GetMethod("ToString",new Type[]{}).DeclaringType == typeof(object));
}
}
...way to determine if an object of unknown type will ToString() into an expected value, and not the type name...
The default implementation of ToString() on object, according to documentation, returns "the fully qualified name of the object's type".
So we could come up with the hypothesis that whenever ToString() is overridden, its output will be "useful" in the sense you specified in the question.
To detect whether a function called is an override, we can make use of this answer, like so:
if(typeof(ObjectX).GetMethod("ToString").DeclaringType == typeof(ObjectX))
{
/* ObjectX has overridden ToString() */
}
else
{
/* ObjectX has inherited ToString() from its base class(es) */
}
Using reflection can add too much overhead, so I reckon it's better to create a generic method and add a constraint like: where T : IFormattable

C# compiler type inference with dynamic function parameters

When I call a function and replace one of the parameters with dynamic, the compiler inferres the function result to be dynamic. I don't understand why this happens.
Example: the inferred type for a is dynamic, so this code compiles, but of course fails at runtime with RuntimeBinderException:
dynamic b = "";
var a = MethodWithoutOverloads("", b);
a.DoesNotExist();
...
public string MethodWithoutOverloads(string a, string b) { ... }
Somebody knows why the type inferred is not the return type of the function?
EDIT: edited to make clear this happens with methods without overloads
You are right in the sense that the compiler could reason out that all String.Format overloads return a string and therefore infer that a must be a string no matter what b really is.
The truth is that the compiler does not do that. It solves the general case, which is good, and because overloads with different return types are valid in C#, it simply assigns the return type as dynamic and lets the runtime figure it out.
Answering your specific question,
public string MethodWithoutOverloads(string a, string b) { ... }
dynamic a = "";
var result = MethodWithoutOverloads(a, a); // result is dynamic.
Lets imagine the compiler decides that result is string and you publish to the wild west your library. Then, later on, you decide to add an overload with the following signature:
public int MethodWithoutOverloads(int a, int b) { ... }
Now, what should the type of result be? And, what happens to existing code that relied on result being strongly typed to string?
string result = MethodWithoutOverloads(someDynamicVariable, someOtherDynamicVariable);
The semantics change completely; before a consumer had a safe strongly typed variable, now he suddenly has a potentially unsafe implicit cast that can blow up in runtime.
Because the compiler doesn't know which method is going to be invoked at run time.
For example, you may have the two methods:
int MyMethod(int a)
{
return 5;
}
double MyMethod(string a)
{
return 6.0;
}
And you write the following code:
dynamic myThing = 5;
var myResult = MyMethod(myThing);
Considering we've explicitly said myThing is dynamic, and this its type is to be determined at runtime, we have no idea which method will be invoked (if any). Thus, we don't know the return type, either.

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();
}

C# Extension Methods - return calling object

I'm new to Extension Methods and exploring what they can do.
Is it possible for the calling object to be assigned the output without a specific assignment?
Here is a simple example to explain:
public static string ExtensionTest(this string input)
{
return input + " Extended!";
}
In the following examples ...
var foo = "Hello World!";
var foo2 = foo.ExtensionTest(); // foo2 = "Hello World! Extended!"
foo.ExtensionTest(); // foo = "Hello World!"
foo = foo.ExtensionTest(); // foo = "Hello World! Extended!"
... is there any way to get foo.ExtensionTest() to result in "Hello World! Extended!" without specifically assigning foo = foo.ExtensionTest()
No, but the reason that will not work has to do with the immutability of strings, and nothing to do with extension methods.
If instead you had a class:
public class SomeClass
{
public int Value {get; set;}
}
And an extension method:
public static void DoIt(this SomeClass someClass)
{
someClass.Value++;
}
Would have the effect of:
var someClass = new SomeClass{ Value = 1 };
someClass.DoIt();
Console.WriteLine(someClass.Value); //prints "2"
The closest you could get to this (which would be weird) would be to accept an out parameter and use that as the return value:
public static void ExtensionTest(this string input, out string output)
{
output = input + " Extended!";
}
Example:
string foo = "Hello World!";
foo.ExtensionTest(out foo);
The funny thing about that is, while it more closely resembles what you're asking about, it's actually slightly more to type.
To be clear: I don't recommend this, unless it's really important to you to make this sort of method call. The probability of another developer uttering "WTF?" upon seeing it has got to be something like 100%.
What you are seeing is due to strings being immutable.
In any case, you will have to do some sort of assignment if you want the object to change.
The 'this' parameter is passed by value, not by reference. So no, you can't modify the variable in the calling program that is aliased by 'this' in your extension method.
No. Strings in .NET are immutable. All public String methods return new instance of String too.
To assign the new value to your variable inside the extension method, you'd need a ref modifyer on the parameter, which the C# compiler does not permit on extension methods (and it would be a bad idea anyway). It's better to make it clear you're changing the variable.
Use the faster StringBuilder for mutable strings and as pointed out the ref or out keyword. StringBuilder is basically an improved linked-list for strings.
Immutable strings were a design decision to allow close behavior to the C language and many other languages.
string str = "foo";
str += "bar"; // str will be free for garbage collection,
//creating a new string object.
//Note: not entirely true in later C# versions.
StringBuilder sb = new StringBuild();
sb.Append("foo");
sb.Append("bar"); // appends object references to a linked list.
See also:
string is immutable and stringbuilder is mutable
http://en.wikipedia.org/wiki/Linked_list

Why System.String beahaves like a value type? (How to write value type classes like string?)

I want to write a 'Date' class that behaves like a Value Type.
for example, Instead of writing a Clone method for setting properties safely, make the Date class to pass by value:
public Date Birthday
{
get { return this.birthday; }
set
{
this.birthday = value.Clone();
} //I want to write this.birthday = value;
//without changing external value when this.Birthday changes
}
I know this is possible because System.String is a class and behaves like a value. for example:
String s1 = "Hello";
String s2 = "Hi";
s1 = s2;
s2="Hello";
Console.WriteLine(s1); //Prints 'Hi'
First I thought writers of this class override '=' operator, but now I know that the '=' operator can not be overridden. so how they write String class?
Edit: I just want to make my Date class to pass it's instances by value, like as String.
First, your string-based example does not illustrate your question.
The thing with DateTime and String is that they are immutable: once an instance is created, it cannot be changed in any way. For example, you cannot add 2 minutes to a DateTime instance by just saying date.Minutes += 2: you'll have to invoke date.AddMinutes(2), which will yield a totally new instance.
To make objects read-only, just follow the same pattern.
public class Date{ ...code...} would be a reference type...not what you want.
public struct Date { ...code...} would be a value type...probably what you want.
The string class is, as it is a class, a reference type...and is immutable..how being immutable effects the behavior of string objects can be confusing at the start.
Given string s1 = "Fish"; s1 is a reference that points to "Fish"...It is the "Fish" bit can never be changed....what s1 points to can be changed. If you then assign s1 = "Tuna"; "Fish" still exists but is no longer referenced and will be GC'd.
In your example after: s1=s2 s1,s2 now reference the same string "Hi"...there is only one "Hi".
I hope I have not gone way below your level.
It's not the '=' operator, it's the fact that when you say
stringThing = "thing";
you're creating a new string, not changing the current string to something else.

Categories

Resources