Reputation: 3109
Recently VS hinted me to use the:
var str = "foo";
var str2 = str[^2..];
Instead of the:
var str = "foo";
var str2 = str.Substring(str.Length - 2);
So, my question is are there any differences between the str[^2..]
and the str.Substring(str.Length - 2)
? I think it is a new C# feature, but I was not able to find any documentation about it. So, I do not know how it is called and what version of C# does it come with.
Here is what I was trying to google:
^ in string access c#
I did not get any related results. Should I google something else?
Upvotes: 17
Views: 17587
Reputation: 8837
Others are correct in that it is just syntax sugar but there is some slight differences. They both call "Substring" however the hat version calls the String.Substring(Int32, Int32)
signature and the later conventional version calls String.Substring(Int32)
signature.
It's interesting that even though str[^2..]
produces more code it seems to have slightly better performance in my quick benchmark.
var str = "foo";
var str2 = str[^2..];
========generates the following IL=============
nop
ldstr "foo"
stloc.0 // str
ldloc.0 // str
dup
callvirt String.get_Length ()
dup
ldc.i4.2
sub
stloc.2
ldloc.2
sub
stloc.3
ldloc.2
ldloc.3
callvirt String.Substring (Int32, Int32)
stloc.1 // str2
ldloc.1 // str2
call Console.WriteLine (String)
nop
ret
And the following conventional version.
var str = "foo";
var str2 = str.Substring(str.Length - 2);
========generates the following IL=============
nop
ldstr "foo"
stloc.0 // str
ldloc.0 // str
ldloc.0 // str
callvirt String.get_Length ()
ldc.i4.2
sub
callvirt String.Substring (Int32)
stloc.1 // str2
ldloc.1 // str2
call Console.WriteLine (String)
nop
ret
Upvotes: 13
Reputation: 670
The reason why google didn't help at this time (besides that c# .0 was new at the time of question) is, becuase its realted to general array access more than specific to string, fortunaly a string is indexable and iterable so the syntax works as well.
https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/proposals/csharp-8.0/ranges
Upvotes: 0
Reputation: 156624
Commenters did a great job on this, but I'm gonna put an answer here so the question can be considered answered.
There is no difference. It's just syntax sugar. Here's what LINQPad shows you'd get in "C# 1.0" terms:
string str = "foo";
int length = str.Length;
int num = length - 2;
int length2 = length - num;
string str2 = str.Substring (num, length2);
Upvotes: 3