manymanymore
manymanymore

Reputation: 3109

C# 8 way to get last n characters from a string

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

Answers (3)

SunsetQuest
SunsetQuest

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.

SharpLab example.

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

Sam Washington
Sam Washington

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

StriplingWarrior
StriplingWarrior

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

Related Questions