Comparing two objects with == operator - c#

I have this code that checks the references of two variables,
I came across this case which is a bit confusing :
string first = "10";
object second = 10.ToString();
dynamic third = second;
Console.WriteLine($"{first == second} {first == third}");
The result is : False True
My first question is why are the first and third references equal? If the third variable is equal to the second it should be False because their object references aren't equal.
And I got confused when I changed the values to "1" like below:
string first = "1";
object second = 1.ToString();
dynamic third = second;
Console.WriteLine($"{first == second} {first == third}");
Then the result becomes: True True
Why does this happen?

I am not sure why it changes when you change it from 10 to 1
I believe this is an implementation detail and you should not rely on it (will try to find something in the specs) but some positive single digit numbers are cached in int.ToString implementation for .NET Core. Here is excerpt from UInt32ToDecStr which is called internally by int.ToString:
// For single-digit values that are very common, especially 0 and 1, just return cached strings.
if (bufferLength == 1)
{
return s_singleDigitStringCache[value];
}
As for equality - please check:
C# difference between == and Equals().
String interning in .Net Framework. (compiler will intern string literals, so all of them will point to the same address in memory)
Using type dynamic
UPD:
Was not able to find anything in specs, but next code behaves differently in .NET Framework and .NET 6 (former one prints 11 times False and the latter prints 10 times True and one False):
var dict = new Dictionary<int, string>()
{
{0, "0"},
{1, "1"},
{2, "2"},
{3, "3"},
{4, "4"},
{5, "5"},
{6, "6"},
{7, "7"},
{8, "8"},
{9, "9"},
{10, "10"},
};
foreach(var kvp in dict)
{
Console.WriteLine(object.ReferenceEquals(kvp.Key.ToString(), kvp.Value));
}
UPD2:
The caching was introduced for performance reasons by this PR and is mentioned in Performance Improvements in .NET Core 3.0 blogpost:
In some sizeable web applications, we found that a large number of strings on the managed heap were simple integral values like “0” and “1”. And since the fastest code is code you don’t need to execute at all, why bother allocating and formatting these small numbers over and over when we can instead just cache and reuse the results (effectively our own string interning pool)? That’s what PR dotnet/coreclr#18383 does, creating a small, specialized cache of the strings for “0” through “9”, and any time we now find ourselves formatting a single-digit integer primitive, we instead just grab the relevant string from this cache.
private int _digit = 4;
[Benchmark]
public string SingleDigitToString() => _digit.ToString();
Method
Toolchain
Mean
Error
StdDev
Ratio
Gen 0
Gen 1
Gen 2
Allocated
SingleDigitToString
netcoreapp2.1
17.72 ns
0.3273 ns
0.3061 ns
1.00
0.0152
–
–
32 B
SingleDigitToString
netcoreapp3.0
11.57 ns
0.1750 ns
0.1551 ns
0.65
–
–
–
–

The answer to the first question is because string equality isn't based on the object references, as reference types are by default.
first and third are both type string, even if only known at runtime, so the System.String's operator == override is called and:
...in turn, calls the static Equals(String, String) method, which performs an
ordinal (case-sensitive and culture-insensitive) comparison.
(source)
I'll also point out that Visual Studio provides a CS0253 compiler warning at first == second:
Possible unintended reference comparison; to get a value comparison,
cast the right hand side to type 'string'
As for the second question... See #GuruStron's answer.

Related

What is the difference between the ranges "^4" and "^4.."?

I was trying to get the substring from a string I am using in my program as follows:
mystring.Substring(mystring.Length - 4)
The Visual Studio IntelliSense recommended I use index and range operators as follows:
mystring[^4..]
I glanced through the documentation here and it seems like using just mystring[^4] would work just fine. Why does the IntelliSense recommend to use the extra .. in there, are there any benefits from adding it?
^4 is an index, representing a single index number which just so happens to be 4 away from the end of the array. This is essentially the same as doing mystring[0], just dynamically figuring out the number based on the length.
^4.. is a range, which means everything between (and including) the 4th-to-last index and the end of the array.
var input = "abcdefghijk";
Console.WriteLine(input[^4]);
Console.WriteLine(input[^4..]);
This prints
h
hijk
The .. operator is used to specify a range, while the values on either side are used to indicate indexes.
Using a single index will give a single value, using the .. operator will give a slice of multiple values:
public static void Main()
{
var array = new int[] { 1, 2, 3, 4, 5 };
Console.WriteLine(array[^3].GetType());
// Equivalent to
// array[new Index(3, fromEnd: true)]
Console.WriteLine(array[^3..].GetType());
// Equivalent to
// array[Range.EndAt(new Index(3, fromEnd: true))]
}
Outputs
System.Int32 // notice the lack of []
System.Int32[]

C# LINQ Query syntax oddity [duplicate]

Why is this .NET enumeration allowed to have a comma in the last field?
Does this have any special meaning?
[FlagsAttribute]
public enum DependencyPropertyOptions : byte
{
Default = 1,
ReadOnly = 2,
Optional = 4,
DelegateProperty = 32,
Metadata = 8,
NonSerialized = 16,
}
It has no special meaning, just the way the compiler works, it's mainly for this reason:
[FlagsAttribute]
public enum DependencyPropertyOptions : byte
{
Default = 1,
ReadOnly = 2,
Optional = 4,
DelegateProperty = 32,
Metadata = 8,
NonSerialized = 16,
//EnumPropertyIWantToCommentOutEasily = 32
}
By comment request: This info comes straight out of the C# Specification (Page 355/Section 17.7)
Like Standard C++, C# allows a trailing comma at the end of an array-initializer. This syntax provides flexibility in adding or deleting members from such a list, and simplifies machine generation of such lists.
Also (to Nick Craver post) its much easier to add new enumerations.
This behaviour appropriate not uniquely to enums. Consider following:
var list = new int[] { 1, 2, 3, };
One other reason: It makes it easier to code gen.
I know that it is an old topic but, another approach that would make sense for this issue is for code versioning systems.
Consider the following example:
//version 1
var myArray = {
"item 1",
"item 2"
};
//version 2
var myArray = {
"item 1",
"item 2", //will be considered a change, it may be considered an erroneous approach
"item 3"
}
Now consider this approach:
//version 1
var myArray = {
"item 1",
"item 2",
};
//version 2
var myArray = {
"item 1",
"item 2", //will not be considered a change, it may be considered an erroneous approach too, but, means that the code wasn't changed intrinsically
"item 3",
};
Anyhow, both approaches may be considered incorrect or correct depending on the situation. I particularly prefer the second approach that makes much more sense when dealing with code versioning systems.
Anyway hope this helps.
Why add trailing commas
Why you should take advantage of this feature when writing code manually?
The resultant patches have less lines affected. This makes them easier to read and review.
Automatic merge and conflict resolution are more accurate because there isn't extra noise to confuse the algorithm.
Examples
Without trailing comma (okay)
Example of adding a line when the previous developer didn't leave a trailing comma:
## -119,7 +119,8 ## namespace SomeApp.Example
{
NameTitle = contact.NameTitle,
GivenName = contact.GivenName,
- FamilyName = contact.FamilyName
+ FamilyName = contact.FamilyName,
+ ProperName = contact.ProperName
},
ContactTelephone1 = contact.ContactTelephone1,
ContactType = contact.ContactType,
Without trailing comma (better)
Example of adding a line when the previous developer left a trailing comma:
## -122,2 +122,3 ## namespace SomeApp.Example
FamilyName = contact.FamilyName,
+ ProperName = contact.ProperName,
},
Note there is one line added in the latter vs one removed and two added. This is much easier for human and machine alike to deal with.
Why did they add it to C#?
As for why it is allowed, as per other answers:
The C# Specification (Page 355/Section 17.7) states:
Like Standard C++, C# allows a trailing comma at the end of an array-initializer. This syntax provides flexibility in adding or deleting members from such a list, and simplifies machine generation of such lists.
This applies to array initializers, object initializers and enums.

How to create an algorithm type?

Say I have two sequences of numbers, A and B.
How can I create an object to describe the relationship between the two sequences?
For example:
A: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9...
B: 0, 2, 4, 6, 8, 10, 12, 14, 16, 18...
B = 2A
The relationship, f() is how we get from A to B.
But given two arbitrary sequences, how can I construct f?
Also, how can I return f to the calling method so that it can simply use it straight away with any number? -- Can you use delegate as a return type?
I have one idea but maybe you could advise me on it: I could use a decorator pattern to build an object containing various operators and constants etc... Then just generate the code. This is very messy and I don't want to use this method.
I'm not asking how to find f, I can do that. I'm asking how to model f.
Sorry if all that is not clear, I don't know how else to explain it.
You could use LINQ expression trees:
var x = Expression.Parameter(typeof(int), "x");
var body = Expression.Multiply(Expression.Constant(2), x);
var lambda = Expression.Lambda<Func<int, int>>(body, x);
var f = lambda.Compile();
or (if the function is known)
Expression<Func<int, int>> lambda = x => 2 * x;
var f = lambda.Compile();
or (without expression trees)
Func<int, int> f = x => 2 * x;
Usage:
var a = new int[] { 0, 1, 2, 3, 4, 5 };
var b = a.Select(f).ToArray();
// b == new int[] { 0, 2, 4, 6, 8, 10 };
See: Expression Class
See also: Expression Tree Basics
Sounds like a job for a fitting program of some kind. Your A sequence looks like the independent variable, and B sequence is the dependent variable.
Least squares fitting is usually used to solve these kinds of problems. You have to be able to make a reasonable guess for the form of the function, calculate some parameters, and see how good your guess/form/parameters are.
If you can't even make a hypothesis of the kind #duffymo speaks of, then the only way I know is breadth-first search in the space of algebraic expression trees. It is brute-force, and extremely slow, but it will find the formula if it is not too complex.
UPDATE: Regarding the representation, it is very easy. If you decide not to use LINQ (I don't know much about it, but the example given by #dtb looks very nice and I don't know why you wouldn't), you can roll your own very easily (of course, these won't auto-compile so nicely, you'd have to interpret them):
Just make nested objects of Expressions, which can be Value or Function. Value can be a Variable (x) or a Constant (1), Function can be UnaryFunction (Sin) or BinaryFunction (Plus). The classes are essentially empty (constructor and a recursive evaluate function).
This is the standard approach you'd take if you took it up with any other language, say Haskell (only with ADTs instead of classes, but the distinction is rather trivial in this case).

Ruby .each with removal of items in collection

I am currently working with an app that allows for runtime addition and removal of items in a drop down list via a rub script. The Ruby looks like this
SAFE = ;
return control if control.CyclesCount == 0;
control.Items.each{|item| control.Items.Remove(item) if item.Value.index('|').nil?};
return control;
control is custom user control and its Items is a ListItemCollction. I am running via unit tests to get my Ruby code correct and running into some trouble. The ListItemColletion I am passing in looks like this ..
var lic = new ListItemCOllection {
new ListItem {Text = "Item2", Value = "8"},
new ListItem {Text = "Item1", Value = "1"},
new ListItem {Text = "Item3", Value = "3|1"},
new ListItem {Text = "Item4", Value = "4"},
new ListItem {Text = "Item5", Value = "5|2"},
new ListItem {Text = "Item6", Value = "6"}
}
Instead of leaving the 2 items with the pipe in them, this code always seems to leave 3 items in the items collection. The 3 depend on the order that I put the items in (while in this order, Item1, Item3, Item5 get left)which leads me to believe that its the remove that is messed up. I have also tried to take a copy of the collection, loop through it, removing from the original so that I was not removing from the collection I was iterating through. I am a relatve noob to Ruby so go easy on me ... but I could use some advice.
Thanks
It is not advisable to change an array while iterating over it. There are some Iterators whose purpose is to change the array.
a= [1,2,3]
b= [1,2,3]
a.delete_if { |x| x == 2 } # => [1,3]
b.reject! { |x| x == 2 } # => [1,3]
a # => [1,3]
b # => [1,3]
Array#delete_if deletes elements of an array. There is only a minor difference to Array#reject
a= [1,2,3]
b= [1,2,3]
a.delete_if { |x| false } # => [1,3]
b.reject! { |x| false } # => nil
a # => [1,2,3]
b # => [1,2,3]
Array#delete_if always returns the remaining array. Array#reject! returns nil instead in case the array remains unchanged.
Some more modifiieng iterators which, do not change the original array:
a= [1,2,3]
a.reject { |x| x == 2 } # => [1,3]
a # => [1,2,3]
Array#reject returns an array without the rejected elements, but does not modify the original array.
a= [1,2,3]
a.select { |x| x != 2 } # => [1,2,3]
a # => [1,3]
Array#select returns an array of only the selected elements, but does not modify the original array.
Modifying a collection while you are iterating through it is never a good idea. If you do that, all hell breaks loose. (Preferably, it would raise some kind of exception, but that's life ...)
However, that's not actually the biggest problem in your code. The biggest problem is that you have commited the mortal sin of Ruby: not knowing Enumerable. (Don't worry: everybody commits that sin. All the time.)
If you want to reject all elements from a collection that satisfy a condition, there's a method for that, and it's called exactly what you would expect: Enumerable#reject!.
So, let's clean this up, shall we?
SAFE = ;
What's that semicolon doing there? It seems you got your C# and Ruby mixed up :-)
(Oh, and also, that line doesn't do anything useful anyway, does it?)
return control if control.CyclesCount == 0;
Again, useless semicolon.
control.Items.each{|item| control.Items.Remove(item) if item.Value.index('|').nil?};
This is where it gets interesting:
control.Items.reject! {|item| item.Value.include?('|') }
Much better, isn't it?
return control;
I personally like to reserve the return keyword for "pure" methods (i.e. methods that don't have side-effects), so I wouldn't use one here since the code modifies control.Items but that is a style choice. Putting it all together, this is how I would write it:
return control if control.cycles_count == 0
control.items.reject! {|item| item.value.include?('|') }
control
Note: I don't have a working install of IronRuby right now, so I am making a few assumptions that I can unfortunately not test:
method name transliteration (CyclesCount -> cycles_count) works,
Value is some kind of String or collection and
ListItemCollection mixes in Enumerable
The latter should be the case if ListItemCollection implements IEnumerable (otherwise I would consider that a bug in IronRuby). If ListItemCollection does not implement IEnumerable (which I would probably consider a bug in ListItemCollection), that is still easily fixed:
class ListItemCollection; include Enumerable end
[BTW: I would also introduce a cycles? method (or a bool HasCycles property on the .NET side), so that you can get rid of the cycle_count == 0 test.]
If you just want to remove items from an array based on a condition, you should use Array#reject!:
control.Items.reject! {|item| item.Value.index('|').nil? };
In order to properly debug this, however, we need to know what control.Items looks like on the Ruby end.

Most succinct way to determine if a variable equals a value from a 'list' of values

If I have a variable in C# that needs to be checked to determine if it is equal to one of a set of variables, what is the best way to do this?
I'm not looking for a solution that stores the set in an array. I'm more curious to see if there is a solution that uses boolean logic in some way to get the answer.
I know I could do something like this:
int baseCase = 5;
bool testResult = baseCase == 3 || baseCase == 7 || baseCase == 12 || baseCase == 5;
I'm curious to see if I could do something more like this:
int baseCase = 5;
bool testResult = baseCase == (3 | 7 | 12 | 5);
Obviously the above won't work, but I'm interested in seeing if there is something more succinct than my first example, which has to repeat the same variable over and over again for each test value.
UPDATE:
I decided to accept CoreyN's answer as it seems like the most simple approach. It's practical, and still simple for a novice to understand, I think.
Unfortunately where I work our system uses the .NET 2.0 framework and there's no chance of upgrading any time soon. Are there any other solutions out there that don't rely on the .NET 3.5 framework, besides the most obvious one I can think of:
new List<int>(new int[] { 3, 6, 7, 1 }).Contains(5);
bool b = new int[] { 3,7,12,5 }.Contains(5);
You can do something similar with .NET 2.0, by taking advantage of the fact that an array of T implements IList<T>, and IList<T> has a Contains method. Therefore the following is equivalent to Corey's .NET 3.5 solution, though obviously less clear:
bool b = ((IList<int>)new int[] { 3, 7, 12, 5 }).Contains(5);
I often use IList<T> for array declarations, or at least for passing one-dimensional array arguments. It means you can use IList properties such as Count, and switch from an array to a list easily. E.g.
private readonly IList<int> someIntegers = new int[] { 1,2,3,4,5 };
I usually use CoreyN's solution for simple cases like that. Anything more complex, use a LINQ query.
Since you did not specify what type of data you have as input I'm going to assume you can partition your input into powers of 2 -> 2,4,8,16... This will allow you to use the bits to determine if your test value is one of the bits in the input.
4 => 0000100
16 => 0010000
64 => 1000000
using some binary math...
testList = 4 + 16 + 64 => 1010100
testValue = 16
testResult = testList & testValue

Categories