.. index:: string; method
   single: . ; object field reference

Some Instance Methods and the Length Property
=================================================

Strings are a special type in C#. We have
used string literals as parameters to functions and we have used the 
special concatenation operator ``+``.
Thus far we have not emphasized the use of objects, or even noted 
what is an object.  In fact strings are objects.  Like other objects,
strings have a general notation for functions that are specially tied to the 
particular type of object.  These functions are called *instance methods*.
They always act on an object of the particular class, but a reference to the
object is not placed inside the parameter list, but *before* the method name and
a dot as in::
 
   csharp> string s = "hello";
   csharp> s.ToUpper();
   "HELLO"

``ToUpper`` (the method converting to upper case) 
does a particular action that makes sense
with strings.  It takes ``s`` 
(the string object reference before the dot in this example)
and returns a *new* string in upper case, based on ``s``.  Since this action
depends only on the string itself, no further parameters are necessary,
and the parentheses after the method name are empty.  The general method syntax is

    *object-reference*\ ``.``\ **methodName** ``(``\ *further-parameters* ``)``

More string methods are listed below, some with further parameters.

.. index:: property
   class; property
   
Data can also be associated with object *properties*.  
A property of a string is its ``Length`` (an ``int``).  References to property values
use dot notation but do not have a parameter list in parentheses at the end::

    csharp> string s = "Hello";
    csharp> s.Length;
    5
    csharp> "".Length;
    0

Be careful: Though 5 is the length of ``s`` in the example above, 
the last character in ``s`` is ``s[4]``.  Using ``s[5]`` would generate
an ``IndexOutOfRangeException``.

String objects have associated string methods which can be used to
manipulate string values. 
There are an enormous number of string methods, but here are just a few
of the most common ones to get you started. The
string object to which the method is being applied is referred to as
**this** string in the descriptions.  After the methods, 
the length property is also listed.
In the heading *this* object is not shown explicitly, so be careful
when applying these methods and the length property: In actual use
in your programs they must be
preceded by a reference to a string, followed by a dot, as shown in 
all the  examples.  The reference to *this* string can be
a variable name, a literal, or any expression evaluating to a string.

.. _string-methods-length:

Summary of String Length and Some Instance Methods
----------------------------------------------------

``int IndexOf(string target)``
    Returns the index of the beginning of the first occurrence of the 
    string ``target`` 
    in **this** string object. Returns -1 if ``target`` not found. Examples:: 
    
        csharp> string greeting = "Bonjour", part = "jo";      
        csharp> greeting.IndexOf(part);
        3                     
        csharp> greeting.IndexOf("jot");
        -1

``string Substring(int start)``
    Returns the substring of **this** string object starting from index ``start`` 
    through to the end of the string object.  Example:
    
    ::    
    
        csharp> string name = "Sheryl Crow";                          
        csharp> name.Substring(7);
        "Crow"      

``string Substring(int start, int len)`` 
    Returns the substring of **this** string object starting from index ``start``, 
    including a total of ``len`` characters.  Example:
    
    ::   
    
        csharp> string name = "Sheryl Crow";                         
        csharp> name.Substring(3,5);
        "ryl C"  
        
    Java programmers:  Note the second parameter is *not* the same as in Java. 

``string ToUpper()``   
    Return a string like **this** string, except all in upper case.  Example:: 
    
      csharp> "Hi Jane!".ToUpper(); 
      "HI JANE!"

``string ToLower()``
    Return a string like **this** string, except all in lower case.  Example:: 
    
        csharp> "Hi Jane!".ToLower();
        "hi jane!" 

``int Length``                           
    Property referring to the length of **this** string object. Example::
    
        csharp> string greeting = "Bonjour"; 
        csharp> greeting.Length;  //no parentheses
        7       

.. index:: immutable

..  warning::
    All of these methods that return a string return a *new* string.  No string method
    alters the original string.  Strings are *immutable*:  
    They are objects that cannot be changed
    after they are first produced.  This is a common source of errors.
    
::

    csharp> string s = "Hello";
    csharp> s.ToUpper()
    "HELLO"
    csharp> s
    "Hello"
    csharp> s = s.ToUpper();
    csharp> s
    "HELLO"    

See that you need an explicit assignment if you *want* the variable associated
with the original string to change.

Further string methods are introduced in :ref:`more-string-methods`.

Time to reflect, thinking back to :ref:`learn-solve`.  
Without forcing all the code details on yourself, 
how can you concisely say what powers you have with strings so far?  
Remember that kernel.

With strings you can: 
Index characters, find a part; extract a part; convert case; determine length.  
These may not be evocative phrases for you.  Find your own. 

When we get to loops, we will find this is useful.

Here is a brief example of a function using several of these methods,

:repsrc:`parenthesized/parenthesized.cs`: 
 
.. literalinclude:: ../source/examples/parenthesized/parenthesized.cs
   :linenos:
 
It is a silly assumption, but until we get to :ref:`If-Statements`, 
we will have to assume there *is*
a parenthesized expression in the parameter string.


String Methods Exercise
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

a.  What is printed by this fragment?  ::

        string w = "quickly";
        Console.WriteLine(w.Length);
        Console.WriteLine(w[w.Length-2]);
        Console.WriteLine(w.Substring(3, 2));
        Console.WriteLine(w.Substring(2));
        Console.WriteLine(w.IndexOf("ti"));
        Console.WriteLine(w.IndexOf("ick"));
        int k = w.IndexOf("c");
        Console.WriteLine("{0} {1} {2} {3}", 
           k, w[k], w[k-3], w.Substring(k));

#.  What is printed by this fragment?  ::

        string s = "HELLO!", t = s.ToLower();
        Console.WriteLine(s+t);

Play with csharp:  Declare other strings and make up
string expressions with these methods 
for which you predict the value and then test.


