none
VB.Net Mid function in C#

    Question

  • The equivalent to the VB.Net Mid() function in C# seem to be the .Substring() method.

    However, this only seems to retrieve the string/characters.

    In VB.Net, you can say for example:

    Dim sText As String = "This is your test"

    Mid(sText, 10, 1) = Mid(sText, 10, 1).ToUpper()

    This would replace whatever character is at position 10 with a capitalized version.

    However, substring() in C# will not allow you to assign a value.

    How would I do the same thing in C#?

    Thanks,
    Darren

    Thursday, March 13, 2008 5:27 PM

Answers

  • Marc is absolutely right.  A good way to see the differences between VB.NET and C# is to look at the VB.NET assembly with Lutz Reflector - which will show the C# equivalent of the MSIL assembler generated by VB.NET.

     

    In your case, the code generated by Mid(sText, 10, 1) = Mid(sText, 10, 1).ToUpper() would look like the following in C# - a call to a compatibility helper method in Microsoft.VisualBasic.Dll.

    Code Snippet
    Microsoft.VisualBasic.CompilerServices.StringType.MidStmtStr(ref sText, 10, 1, Microsoft.VisualBasic.Strings.Mid(sText, 10, 1).ToUpper());

     

     

    So while you have access all the VB compatibility functionality in C# by adding references to the VB compatibility assemblies, in practice you'd want to use the stuff in the standard framework assemblies.

     

    As an aside, I think it's a pity the framework doesn't include an equivalent of VB's Mid function.  String.Substring nearly does the job, but, unlike Mid, will throw an exception if the requested substring goes beyond the length of the input string.

     

    I.e. for a string "Short String"

     

    Mid(7, 6) returns the same as String.Substring(6,6) = "String"

    Mid(7, 20) returns "String"

    String.Substring(6,20) throws an exception.

     

     

     

    Thursday, March 13, 2008 9:35 PM
  • Reference Microsoft.VisualBasic and use Mid.

    Friday, March 14, 2008 12:08 PM

All replies

  • I'm not too familiar with VB.Net, so I'll have to take your word for it - but .Net strings are immutable. As such, you'd need to create a new string. Perhaps something like below - obviously you could wrap it up a bit for convenience:

     

    Code Snippet

    string text = "This is your test";

    char[] buffer = text.ToCharArray();

    buffer[10] = char.ToUpper(buffer[10]);

    text = new string(buffer);

     

    Thursday, March 13, 2008 7:39 PM
  • Marc is absolutely right.  A good way to see the differences between VB.NET and C# is to look at the VB.NET assembly with Lutz Reflector - which will show the C# equivalent of the MSIL assembler generated by VB.NET.

     

    In your case, the code generated by Mid(sText, 10, 1) = Mid(sText, 10, 1).ToUpper() would look like the following in C# - a call to a compatibility helper method in Microsoft.VisualBasic.Dll.

    Code Snippet
    Microsoft.VisualBasic.CompilerServices.StringType.MidStmtStr(ref sText, 10, 1, Microsoft.VisualBasic.Strings.Mid(sText, 10, 1).ToUpper());

     

     

    So while you have access all the VB compatibility functionality in C# by adding references to the VB compatibility assemblies, in practice you'd want to use the stuff in the standard framework assemblies.

     

    As an aside, I think it's a pity the framework doesn't include an equivalent of VB's Mid function.  String.Substring nearly does the job, but, unlike Mid, will throw an exception if the requested substring goes beyond the length of the input string.

     

    I.e. for a string "Short String"

     

    Mid(7, 6) returns the same as String.Substring(6,6) = "String"

    Mid(7, 20) returns "String"

    String.Substring(6,20) throws an exception.

     

     

     

    Thursday, March 13, 2008 9:35 PM
  • Although they have the same name, what you have here is the Mid function (on the right side of the assignment) and the Mid 'statement' (on the left side).

    The actual C# equivalent is (via Instant C#):

    sText = sText.Remove(9, 1).Insert(9, (sText.Substring(9, 1).ToUpper()));

     

     

    Thursday, March 13, 2008 11:22 PM
  • > sText = sText.Remove(9, 1).Insert(9, (sText.Substring(9, 1).ToUpper()));

    Just a small point - although functionally identical, this requires a lot of intermediary strings (one for the remove, one for the substring, one for the ToUpper() and finally one for the insert). They will all be GEN-0 of course, but it is smoething you might want to avoid if in a tight loop... this will be compounded if you need to change multiple characters, in which case the buffer approach is even more desirable. If you need to insert/remove characters (i.e. the length before and after is likely to be different) multiple times, then StringBuilder would be a good option for a working copy.

     

    Friday, March 14, 2008 5:13 AM
  • Reference Microsoft.VisualBasic and use Mid.

    Friday, March 14, 2008 12:08 PM
  • I suppose my disappointment with this, as a fan of C#, is that this is quite a basic operation: you just want to replace one character in a string with another.  I felt that this should feature as a base method.

     

    I would have liked to have seen an overload of the Replace method, something along the lines of:

     

    newText = originalText.Replace(<index>, <newChar>)

     

    and possibly

     

    newText = originalText.Replace(<index>, <newString>)

     

    ... the second overload would just overwrite whatever characters previously existed or throw an exception if <newString> exceeded the length of the original string.

     

    I suppose the behaviour could also be modified to extend the string if <newString> was longer than originalText.

     

    I have thought for some time that some of VB's functionality, though arguable less graceful, is more logical than that of C#.

     

    Saturday, March 15, 2008 10:16 AM
  • The issue is that normally you want to do more than one thing... the immutable nature of strings makes this expensive to do what you want directly. However, you can simply use a StringBuilder which offers everything you want:

     

    Code Snippet

    StringBuilder sb = new StringBuilder(existingString);

    sb[3] = 'c';

    sb.Replace(...); // various overloads

    string newString = sb.ToString();

     

     

     

    If you *only* want a single operation in your example, then fine - note that in C# 3 you can use extension methods to make this quite simple (if you want):

     

    Code Snippet

    string foo = "abc";
    string bar = foo.Replace(1, 'd');
    ...
    static class StringExt {
        public static string Replace(this string oldString, int index, char value) {
            char[] buffer = oldString.ToCharArray();
            buffer[index] = value;
            return new string(buffer);
        }
    }

     

    Saturday, March 15, 2008 10:34 AM