Let's say I have an integer that I need to convert to a string (I might be displaying the value to the user by means of a TextBox, for example.
Should I prefer .ToString() or Convert.ToString(). They both do the same thing (don't they?).
int someValue = 4;
// You can do this
txtSomeValue.Text = someValue.ToString();
// Or this...
txtSomeValue.Text = Convert.ToString(someValue);
Assuming that there is no runtime difference between the two, then my reasons come down to aesthetics and consistency. Recently I have been favouring Convert.ToString() as to me it says "hey, I want the value of this thing as a string". However I know that this is not strictly true...
One test is
//This will set the variable test to null:
string test = Convert.ToString(ConfigurationSettings.AppSettings["Missing.Value"]);
//This will throw an exception:
string test = ConfigurationSettings.AppSettings["Missing.Value"].ToString();
Got the above ready example from http://weblogs.asp.net/jgalloway/archive/2003/11/06/36308.aspx
You can find some benchmarks between the two at
http://blogs.msdn.com/brada/archive/2005/03/10/392332.aspx
So, it depends what you prefer and what your style is.
With its large number of overloads, Convert.ToString() is useful as a catch-all for all sorts of input types, handy when you are dealing with a potential range of types. If you know that your input is definitely an "int", I would use the ToString() method on it directly (that's what Convert.ToString() is going to be calling by proxy anyways.)
Related
I expect the following call to the Parse method to return the enum member EN_CA but it returns EN instead.
Enum.Parse(LanguageType, "EN_CA", true);
where:
enum LanguageType
{
EN = 0,
EN_CA = 0,
FR = 1
}
It seems like the Parse method just grabs the first member that maps to the value of the parameter that is passed into it.The Parse method seems to be loosing information during the conversion from string to enum member. Changing the order of EN_CA and EN would make the above call to return EN_CA but that is not going to solve the problem since it would cause a similar issue when calling the method for "EN".
Additional context related information: In my code, the LanguageType Enum is represent the index for a dictionary and these indices are used for localizing the language.
Does anyone have any idea of how to map two enum member to the same value while being able to get proper member from Enum.Parse? Do I just need to implement my own version of Enum.Parse which doesn't collapse the members with the same value into one?
An enum member is distinct from other enum members if and only if it has a different value. Effectively the members of the enumeration are named constants, with no real distinction between them other than the value they hold.
In your LanguageType enum you have two labels for the same value, and no way to distinguish them. Try this:
Console.WriteLine("{0} == {1} ? {2}",
LanguageType.EN.ToString(),
LanguageType.EN_CA.ToString(),
LanguageType.EN == LanguageType.EN_CA);
The output is:
EN == EN ? True
The same thing happens when you assign LanguageType.EN_CA to a variable, then examine the variable later to see what it contains. What you get is LanguageType.EN.
The key here is that the value of the member is all-important in most instances, with the position of the member being the tie-breaker during collisions. When two members have the same value the member that is declared first is the one that you will see whenever you do string conversions, including when you examine the value in the IDE.
So in effect you have a value LanguageType.EN_CA that is only an alias to the value LanguageType.EN.
While I can think of a couple of cute uses for this - like parsing incoming data that has multiple representations for the same value - it is really quite a terrible thing to do in most real-world environments, especially if you want to be able to do fully symmetric serialization/deserialization.
Now, as to your localization Dictionary...
It costs very little to store the same class object multiple times in a Dictionary, since class objects are stored by reference. Assuming you have a Localization class, the following code is not particularly inefficient in terms of storage:
enum LanguageType
{
EN, EN_CA, EN_US, EN_GB, EN_AU, FR
}
Dictionary<LanguageType, Localization> localizations = new Dictionary<LanguageType, Localization>();
localizations[LanguageType.EN] = new Localization("EN");
localizations[LanguageType.EN_CA] = localizations[LanguageType.EN];
localizations[LanguageType.EN_US] = localizations[LanguageType.EN];
localizations[LanguageType.EN_GB] = localizations[LanguageType.EN];
localizations[LanguageType.EN_AU] = localizations[LanguageType.EN];
Even if the Localization object contains a huge collection of resources, the above code only ever creates one instance of it. You get distinct values for the LanguageType members, and the Dictionary does the mappings for you.
You defined 0 twice in your enum - this will not work. Each value has to be unique or how else would an enum recognize its values - it is actually stored as integer.
Change it to:
enum LanguageType
{
EN = 0,
EN_CA = 1,
FR = 2
}
EDIT:
As pointed out by Greenish, you can define multiple names for the same value which acts as a sort of an alias. Using both or multiple names return the same value. If you try to get the string value from an integer value, you will get the first value defined for that integer.
In your case, you cannot achieve what you need using enums. You should probably build your own custom class to achieve that.
Enums basically are named integers. And it is possible to assign different names for a single number (as in your example for 0).
Enum.Parse searching for a first correct instance - and here you have a valid name as 0 == 0. So the solution is to change your numbers (or even just get rid of them as they are 0, 1, 2)
enum LanguageType
{
EN,
EN_CA,
FR
}
I thought of a way but it's messy fragile and naff. There again it illustrates the hole you have dug for yourself..
int index = Enum.GetNames(typeof(LanguageType)).indexof("EN_CA")
will give you 1
then something like
switch(index)
{
case 0 : return LanguageType.EN;
case 1 : return LangaugeType.EN_CA;
case 2 : return LanguageType.FR;
default : // throw some useful exception maybe
break
}
will return the member you want.
Horrible isn't it?
Enum.GetValues(typeof(LanguageType)) would return [0,0,1] and using indexof 0 on it is of course 0, which is why Parse is giving you the result it is.
The =0 specifies the representation of the enum's value in the underlying type (int). You've given both EN and EN_CA the same representation, namely 0, so now they've effectively become two labels for the same value.
Enum.Parse returns this value and it'll equal both labels.
The underlying problem is that you're trying to code a hierarchical concept, into a flat enum. For some purposes all english speaking cultures should be treated equal, for other purposes you'd like to distinguish between them.
The solution, I think, is to use the already present mechanisms for localizing your application, in particular CultureInfo should replace your enum and Resources your lookup dictionary.
I was a little surprised that this use of enum is allowed :)
But the MSDN documentation explicitly states it is valid and gives an example of how it can be useful:
enum Color
{
Red,
Green,
Blue,
Max = Blue
}
So here is how I fixed my problem:
I was not able to find a clean fix for the problem by getting Enum.Parse method return what I was expecting it to.(please see the note*)
My fix was to apply GroupBy(LanguageIndex) on the resulting dictionary which had its index duplicated and therefore throwing an exception. Since I wanted EN_CA and EN to have the same value in the enum that gave me what I was looking for without throwing an exception.
I can see that my fix is not an actual answer to the question that I initially asked, ignoring the context; though I though it might still be applicable to other contexts with a similar issue.
note* : I could have implemented my own version of Enum.Parse - Please see this answer for an alternative implementation - but that required me to put smelly hardcoded stuff into my code, so I just gave up on fixing the Parse method.
It seems like .NET goes out of its way to make strings that are equal by value equal by reference.
In LINQPad, I tried the following, hoping it'd bypass interning string constants:
var s1 = new string("".ToCharArray());
var s2 = new string("".ToCharArray());
object.ReferenceEquals(s1, s2).Dump();
but that returns true. However, I want to create a string that's reliably distinguishable from any other string object.
(The use case is creating a sentinel value to use for an optional parameter. I'm wrapping WebForms' Page.Validate(), and I want to choose the appropriate overload depending on whether the caller gave me the optional validation group argument. So I want to be able to detect whether the caller omitted that argument, or whether he passed a value that happens to be equal to my default value. Obviously there's other less arcane ways of approaching this specific use case, the aim of this question is more academical.),
It seems like .NET goes out of its way to make strings that are equal
by value equal by reference.
Actually, there are really only two special cases for strings that exhibit behavior like what you're describing here:
String literals in your code are interned, so the same literal in two places will result in a reference to the same object.
The empty string is a particularly weird case, where as far as I know literally every empty string in a .NET program is in fact the same object (i.e., "every empty string" constitutes a single string). This is the only case I know of in .NET where using the new keyword (on a class) may potentially not result in the allocation of a new object.
From your question I get the impression you already knew about the first case. The second case is the one you've stumbled across. As others have pointed out, if you just go ahead and use a non-empty string, you'll find it's quite easy to create a string that isn't reference-equal to any other string in your program:
public static string Sentinel = new string(new char[] { 'x' });
As a little editorial aside, I actually wouldn't mind this so much (as long as it were documented); but it kind of irks me that the CLR folks (?) implemented this optimization without also going ahead and doing the same for arrays. That is, it seems to me they might as well have gone ahead and made every new T[0] refer to the same object too. Or, you know, not done that for strings either.
If the strings are ReferenceEqual, they are the same object. When you call new string(new char[0]), you don't get a new object that happens to be reference-equal to string.Empty; that would be impossible. Rather, you get a new reference to the already-created string.Empty instance. This is a result of special-case code in the string constructor.
Try this:
var s1 = new string(new char { 'A', 'b' });
var s2 = new string(new char { 'A', 'b' });
object.ReferenceEquals(s1, s2).Dump();
Also, beware that string constants are interned, so all instances of the literal "Ab" in your code will be reference equal to one another, because they all refer to the same string object. Constant folding applies, too, so the constant expression "A" + "b" will also be reference equal to "Ab".
Your sentinal value, therefore, can be a privately-created non-zero-length string.
You can put non-printable characters into the string... even the 0/nul character. But really, I'd just use null for the sentinel value, and try to ensure code elsewhere is using the empty string instead of null.
So I want to be able to detect whether the caller omitted that argument, or whether he passed a value that happens to be equal to my default value.
I've never done this before, but my thoughts would be to make a Nullable class... but instead of Nullable it would be Parameter and would keep track on whether or not it has been assigned anything (including null).
I have code where I get a string as input, and I compare it with an integer.
I saw that integer variable also has an Equals function that accepts a string parameter.
I have used it directly thinking it will typecast it.
It did not give any compile time or runtime error, but it always gives a false result.
For example,
int sessionId = 1;
string requestId="1"
return sessionId.Equals(requestId);
sessionId.Equals(requestId) always gives false.
Why is the reason for such behavior? If there is a reason, why are they allowing it run without error?
Integers and strings are always different, and thus "1".Equals(1) returns false.
It compiles because object.Equals(object other) takes an object as the right side, and thus accepts any type.
The reason why this happens is that a string "0" is not the same as 0, so it returns false.
Why is such behavior supported? Because the Equals method allows you to pass an object as a parameter, and a string is in an object, so you are "allowed" to do it. As you have found, it's not very useful in this case.
To solve your problem either get a string representation of the integer, or parse your string to an integer, then compare.
E.g. Try
return (sessionId.ToString() == requestId);
or
return (sessionId == int.Parse(requestId));
If you choose the later you may need to consider if the Parse could fail and how you might handle that.
Yes, Equals takes any type on the right side because it is requires an object. But inside the function it requires the same type as the left side. IMHO there's no need to throw an exception for type mismatching because one only wants to know about equality of two types.
Decompiled Equals of int:
public override bool Equals(object obj)
{
return obj is int && this == (int)obj;
}
If someone shows you a car and a banana, and asks whether they are the same thing, would you throw a temper tantrum because a car is a vehicle and a banana is a fruit, or would you simply say "no, they are not the same thing"?
In many languages, trying to compare an integer and a string will yield a compiler error, because the compiler knows that the integer and the string cannot possibly be the same thing and thus any code that tried to compare them would almost certainly be erroneous. On the other hand, when you say sessionId.Equals(requestId), the compiler knows that you are asking that requestId be passed to the Int32 override of Equals. Since that override can accept a reference to any kind of heap object, it has no problem passing the string "1". That method in turn knows that it was given something which isn't the same as an Int32 with the value 1. It doesn't know that the calling code can't possibly supply anything that would match an Int32; all it knows is that the particular value isn't the same, and because the value isn't the same it perfectly happily returns false.
Shouldn’t we be using String.Compare for string comparison and forget about Equals?
I did have the same problem and I believe the function Equals should throw an exception. In my case, I have been comparing a string with a Boolean.
The discussion by now went wrong way. This is my view:
If a comparison between objects belonging to two different classes always returns false, then they do not need to be compared in the first place.
If there is a need to have a function that bypasses type checking, there should be one. However, having the function Equals positioned as a recommended method for string comparison and in the same time introducing the possibility of unneeded bugs (which may sit in your program for eternity) is a kind of irresponsible.
Moreover, it is extremely misleading that the function call String.Equals(string1, string2, StringComparison. xxx) also accepts non-string arguments. Thus not only string1.Equals(string2).
If that is by design, then it is a poor design.
Here's my method:
public static bool ValidateAddressCount(ref long o_addressCount)
{
// o_addressCount is modified here
//return true or false
}
I've reached some case when i don't care what the method returns, i just need the o_adressCount
Is it a good practice to use this method in the following way:
long addressCount = 0;
ValidateAddressCount(ref addressCount); //without assigning the returned value to any variable
//use address count
Also, can anyone explain why this works in .net?
Thank you
Its upto the developer. No hard rules in it.
Like in bool int.TryParse(string s, out int a){}
When we pass a value to be converted into int value it returns a bool value and uses the out variable to send converted value.
Sometimes we need to check whether it has been converted or not. That's where we use return value.
string str = "1";
int a = 0;
if(int.TryParse(str, out a))
MessageBox.Show("Converted");
else
MessageBox.Show("Not Converted");
Tryparse can be used simply as
bool b = int.TryParse(str, out a);
Let's say bool value returned is of no use to me. Then why waste memory by creating a variable(b), assigning it a value and not using it. So i will write it as
int.TryParse(str, out a);
Why it works is easy:
long addressCount = 0;
ValidateAddressCount(ref addressCount);
is of the same form as
long addressCount = 0;
true;
Any <expression> ; is a valid statement.
There is a valid question here though:
Why is there no warning for this syntax which is quite likely a mistake?
Because in general it is not a good practice to ignore a return value.
This works because you declared a method with return-value, which means that you may want care about that return-value, but it's not mandatory option.
Use ref/out when calling method want the changes of called method in passed parameter.
Otherwise, it's not a good choice to use ref/out.
You should use dynamic object/tuple if want to return more than one value from called method.
You do not have to use the result of the method, you can just call it for its side effect. However, it's usually a good idea to avoid using ref, if you can. In your case, you can just return long?.
No you dont need to assign the return value.. but in my opinion, method as validateSomething(object) should have a return value if the object is valid or not and it shoud be important to check for the return value.
If the method does something with the object, it shouldnt be called just validateSomething(object), but validateAndChangeSomething(object)... now it is confusing what it is doing and what is the primary output of the validation: the return value or the modified object..
Whilst what you have written works, I don't think it's particularly obvious what your method is doing.
Things have moved on a bit since I first started coding but I believe that nowdays it good practice to make your code readable to humans first and then comment the hell out of it if you really have to do something unexpected.
With that in mind, I'd tweak your code to provide a property to obtain the count and modify the method so that you wouldn't need a parameter.
I know this doesn't answer the "use a method and ignore the return type" part of your question but I think that's subjective on what your are doing at the time.
If I have duplicate values in a C# enum, saying
enum MyE {
value1 = 1,
value2 = 2,
valued = 1
}
What should be the values of the following strings?
MyE N = (MyE)1;
string V1 = N.ToString();
string V2 = GetName(MyE, 1);
Is it true that V1 and V2 must contain the same values?
What these values should be?
I haven't found anything in MSDN or here concerning such a «dereferencing» of enums with duplicates, point me to a link, please, if I missed that.
Experimentation shows that:
V1 = "value1"
and
V2 = "value1"
However, this isn't guaranteed. The MSDN page on Enum.GetName states:
If multiple enumeration members have the same underlying value, the GetName method guarantees that it will return the name of one of those enumeration members. However, it does not guarantee that it will always return the name of the same enumeration member. As a result, when multiple enumeration members have the same value, your application code should never depend on the method returning a particular member's name.
From the "Remarks" section on the Enum.GetName method documentation (http://msdn.microsoft.com/en-us/library/system.enum.getname.aspx), it says:
If multiple enumeration members have the same underlying value, the GetName method guarantees that it will return the name of one of those enumeration members. However, it does not guarantee that it will always return the name of the same enumeration member. As a result, when multiple enumeration members have the same value, your application code should never depend on the method returning a particular member's name.
I ran a test to see what would happen experimentally, and it always returned the first value defined (in your example, value1), but according to the official documentation above, you cannot rely on that (see comment by #gluk47, indicating different behavior in the wild).
I disagree with other answers statements
... this isn't guaranteed ...
... you cannot rely on that ...
as well as with msdn statement:
... your application code should never depend on the method returning a particular member's name ...
The story
There was an enum in my software
enum Blabla { A = 0, B = 1, C = 2, D = 3 }
at some point A value changes to AA and later AA changes to AAA. To keep backward compatibility I had to do
enum Blabla { A = 0, AA = 0, AAA = 0, B = 1, C = 2, D = 3 }
This allows to deserialize old enum value (made by older versions of software) as AAA.
Then there was a report which prints Blabla setting value. And at some point every customer using new version start telling me what instead of AAA they see AA value. All of them see AA (and no one report seeing A).
What I did? I simply change the order (until result was AAA)
enum Blabla { AAA = 0, A = 0, AA = 0, ...}
and made a test to ensure what Blabla.AAA will be output as AAA. Problem solved?
The proof
Looking at sources of Enum.ToString() (or Enum.GetName()), it uses GetEnumName(), which calls Array.BinarySearch() for sorted array of values to find an index of value.
The result of binary search is deterministic: providing it with the same parameters will return same result.
So:
if you don't change enum, then result will be the same.
it is possible to find result experimentally (or perhaps by understanding how binary search works and how enum will be processed).
there is no easy rule to determine result (e.g. you can't say "it always return first defined value").
it's unlikely what enum format will be changed (e.g. order of definition and order of list of values differs) or Enum.ToString() will be changed, it can happens however, so make sure you have tests for cases where you rely on return value.
Well, because there are no guarantees about the order and obsolete attribute seems to have no impact on Enum methods, I would usually suggest to use a string property for serialization purpose and use custom code to handle obsolete values.
That way, the primary Enum has no duplicate and contains only current values.
Depending on the serialization framework, you might be able to mark the string property as serializable but obsolete and the actual property used in code to be ignored by serialization.
To handle obsolete values in the string property setter, you can either use an [Obsolete] enum or a switch statement. Typically, I would probably use the former if I have a lot of obsolete values to handle and the latter if I have only a few values to handle.
Also it might make sense to put the code in an helper class or an extension method particularly if you load or store that value from a bunch of places.
Although I have not tried it much in production code, I am wondering if it would be better to use a struct instead of an enum to have more control... but I think it need a lot of boilerplate code that cannot easily be made generic.
Whilst this might be a little late to the Party, this may not be the greatest idea, however, the one work around I did find in my case in which I've had to use duplicate enums is to use the following from the question here; Get String Name from Enum in C#
var name = nameof(DeclaredEnum.EnumName);
Resulting in:
EnumName
You can read more Here as to how it actually works.