CPP225
Object Oriented
Programming I
C# Basics
-
Part III
Öğr. Gör.
İhsan Can İÇİUYAN
2 Object Oriented Programming
Contents
Working with Strings
String Concatenation
Escape Characters
String Interpolation
Verbatim Strings
Strings and Equality
StringBuilder Class
Type Conversion
The checked Keyword
Project-wide Overflow Checking
The unchecked Keyword
Implicitly Typed Variables
3 Object Oriented Programming
Working with Strings
System.String → provides methods for string manipulation
4 Object Oriented Programming
Working with Strings
EX: A program to perform some operations on a local string
variable.
Code: 23_Strings.cs
Output:
Value of name: Freddy
name has 6 characters.
name in uppercase: FREDDY
name in lowercase: freddy
name contains the letter y?: True
New name: Fred
NB: The name variable has not changed at all; rather, you receive a
new string in a modified format.
5 Object Oriented Programming
String Concatenation
String variables can be connected to build larger strings via the +
operator. → string concatenation
Consider the following example:
string s1 = "Object Oriented ";
string s2 = "Programming (OOP)";
string s3 = s1 + s2;
Console.WriteLine(s3);
It is also possible to perform string concatenation by calling
String.Concat() directly:
string s1 = "Object Oriented ";
string s2 = "Programming (OOP)";
string s3 = String.Concat(s1, s2);
Console.WriteLine(s3);
6 Object Oriented Programming
Escape Characters
Escape characters → qualifies how the character data should be
printed to the output stream
Consider the following example:
string strWithTabs = "Model\tColor\tSpeed\tName\a ";
Console.WriteLine(strWithTabs);
Console.WriteLine("Everyone loves \"Hello World\"\a ");
Console.WriteLine("C:\\MyApp\\bin\\Debug\a ");
7 Object Oriented Programming
String Interpolation
We can use an alternative syntax to build string literals that contain
placeholders for variables. → string interpolation
This approach allows you to directly embed the variables.
Consider the following example:
string name = "Aydin";
int age = 21;
// Using curly bracket syntax
string greeting = string.Format("Hello {0}! You are {1} years old.", name, age);
Console.WriteLine(greeting);
// Using string interpolation
string greeting2 = $"Hello {name}! You are {age} years old.";
Console.WriteLine(greeting2);
8 Object Oriented Programming
String Interpolation
The string you are constructing begins with a dollar sign ($) prefix.
The curly brackets still are used to mark a variable placeholder.
However, rather than using a numerical tag, you are able to place
the variable directly into the scope.
Advantage: This new formatting syntax is a bit easier to read.
Consider the following example:
string city = "Istanbul";
int area = 5641;
string text = $"City: {city}, area: {area}";
Console.WriteLine(text);
9 Object Oriented Programming
Verbatim Strings
Using verbatim strings, you print out a string as it is.
To create a verbatim string → prefix a string literal with the @ symbol
Consider the following example:
Console.WriteLine(@"C:\MyApp\bin\Debug");
Verbatim strings can be used to preserve whitespace for strings that
flow over multiple lines:
string myLongString = @"This is a very
very
very
long string.";
Console.WriteLine(myLongString);
10 Object Oriented Programming
Verbatim Strings
Using verbatim strings, you can also directly insert a double quote
into a literal string by doubling the " token:
Console.WriteLine(@"I say ""Hello World!"" every day.");
Verbatim strings can also be interpolated strings, by specifying both
the interpolation operator ($) and the verbatim operator (@).
string interp = "interpolation";
string myLongString2 = $@"This is a very
very
long string with {interp}.";
Console.WriteLine(myLongString2);
NB: The order of the operators doesn’t matter. Using either $@ or @$
will work.
11 Object Oriented Programming
Strings and Equality
Performing a test for equality on reference types → returns true if
the references are pointing to the same object in memory
Reference type → an object allocated on the garbage-collected
managed heap
The string data type is a reference type.
The equality operators have been redefined to compare the values
of string objects, not the object in memory to which they refer.
The equality operators by default perform a case-sensitive, culture-
insensitive, character-by character equality test on string objects.
12 Object Oriented Programming
Strings and Equality
EX: A program to perform equality test on string objects.
Code: 28_StringEquality.cs
Output:
s1 = Hello!
s2 = World!
s1 == s2: False
s1 == Hello!: True
s1 == HELLO!: False
s1 == hello!: False
s1.Equals(s2): False
World.Equals(s2): True
NB: Every string literal (such as "Hello!") is a valid System.String
instance.
13 Object Oriented Programming
Working with Strings
After you assign a string object with its initial value, the character
data cannot be changed.
The methods of the string type are returning a new string object
in a modified format.
Consider the following example:
string s1 = "This is my string.";
Console.WriteLine("s1 = {0}", s1);
string upperString = s1.ToUpper();
Console.WriteLine("upperString = {0}", upperString);
Console.WriteLine("s1 = {0}", s1);
14 Object Oriented Programming
Working with Strings
Examine the relevant output:
s1 = This is my string.
upperString = THIS IS MY STRING.
s1 = This is my string.
The original string object (s1) is not uppercased when calling
ToUpper().
Rather, you are returned a copy of the string in a modified format.
STRINGS ARE IMMUTABLE!
15 Object Oriented Programming
Working with Strings
The same law of immutability holds true when you use the
assignment operator:
string s2 = "My other string";
s2 = "New string value";
A new string object is loaded on the managed heap.
The previous string object that contained the value "My other
string" will eventually be garbage collected.
The string class can be inefficient and
result in bloated code if misused.
16 Object Oriented Programming
StringBuilder Class
Representing the word processing data using string objects
Making unnecessary copies of string data
StringBuilder → represents a mutable string of characters
Defined in the System.Text namespace
When you call members of this type:
you are directly modifying the object’s internal character data
not obtaining a copy of the data in a modified format
StringBuilder class, Microsoft Learn: Link
17 Object Oriented Programming
StringBuilder Class
Consider the following example:
StringBuilder sb = new StringBuilder("** Superhero Movies **");
sb.Append("\n");
sb.AppendLine("Iron Man");
sb.AppendLine("Captain America");
sb.AppendLine("Spider-Man " + "3");
sb.AppendLine("Avengers");
Console.WriteLine(sb.ToString());
sb.Replace("3", "No Way Home");
Console.WriteLine(sb.ToString());
Console.WriteLine("sb has {0} characters.", sb.Length);
We have constructed a StringBuilder object set to the initial value
"** Superhero Movies **". We are appending to the internal buffer
and replacing characters.
18 Object Oriented Programming
StringBuilder Class
By default, a StringBuilder is only able to initially hold a string of 16
characters or fewer (but will expand automatically if necessary).
The default starting value can be changed via an additional
constructor argument:
StringBuilder sb = new StringBuilder("** Superhero Movies **", 256);
We created a StringBuilder with an initial size of 256.
If you append more characters than the specified limit
the StringBuilder object will copy its data into a new instance
and grow the buffer by the specified limit
19 Object Oriented Programming
Type Conversion
Consider the following example:
static void Main(string[] args)
{
short num1 = 9, num2 = 10;
Console.WriteLine("{0} + {1} = {2}",
num1, num2, Add(num1, num2));
}
static int Add(int x, int y)
{
return x + y;
}
The Add() method expects to be sent two int parameters.
However, the Main() method is sending in two short variables.
The program compiles and executes without error.
20 Object Oriented Programming
Type Conversion
In the previous program, there is no possibility for loss of data.
The maximum value of a short (32,767) is within the maximum
range of an int (2,147,483,647).
The compiler implicitly widens each short to an int.
Widening → implicit upward cast that does not result in loss of data
21 Object Oriented Programming
Type Conversion
Consider the following example:
static void Main(string[] args)
{
short num1 = 30000, num2 = 30000;
short answer = Add(num1, num2);
Console.WriteLine("{0} + {1} = {2}",
num1, num2, answer);
}
static int Add(int x, int y)
{
return x + y;
}
In this case, the compiler will give an error.
22 Object Oriented Programming
Type Conversion
In the previous program, the value returned by the Add() method
(60,000) cannot be stored in a short.
The value 60,000 overflows the bounds of the short data type.
The CLR is unable to apply a narrowing operation.
Narrowing → the operation where a larger value is stored within a
smaller data type variable
Type Conversion Tables in .NET, Microsoft Learn: Link
All implicit narrowing conversions result in a compiler error.
23 Object Oriented Programming
Type Conversion
Consider the following example:
byte myByte = 0;
int myInt = 200;
myByte = myInt;
Console.WriteLine("Value of myByte: {0}", myByte);
This code also results in a compiler error.
Any attempt to assign a value to a variable that is not implicitly
convertible, will generate a compilation error.
The C# language is a strongly typed language.
24 Object Oriented Programming
Type Conversion
To perform a narrowing operation, you must apply an explicit cast.
Consider the following example:
static void Main(string[] args)
{
short num1 = 30000, num2 = 30000;
short answer = (short)Add(num1, num2);
Console.WriteLine("{0} + {1} = {2}",
num1, num2, answer);
}
static int Add(int x, int y)
{
return x + y;
}
25 Object Oriented Programming
Type Conversion
The previous program compiles; however, the result of the addition
is completely incorrect.
Explicit cast → to force the compiler to apply narrowing conversion
In the following example, there is no loss of data.
byte myByte = 0;
int myInt = 200;
myByte = (byte)myInt;
Console.WriteLine("Value of myByte: {0}", myByte);
An explicit cast may result in a loss of data.
26 Object Oriented Programming
The checked Keyword
Consider the following example:
byte b1 = 100;
byte b2 = 250;
byte sum = (byte)Add(b1, b2);
Console.WriteLine("sum = {0}", sum);
System.Byte can hold a value only between 0 and 255.
The sum contains the overflow value 94 (350 - 256 = 94).
By default, overflow/underflow conditions occur without error.
27 Object Oriented Programming
The checked Keyword
To test for overflow conditions → wrap a statement (or a block of
statements) within the checked keyword
If an overflow has occurred, you will receive a runtime exception:
System.OverflowException
Consider the following example:
byte b1 = 100;
byte b2 = 250;
try
{
byte sum = checked((byte)Add(b1, b2));
Console.WriteLine("sum = {0}", sum);
}
catch (OverflowException ex)
{
Console.WriteLine(ex.Message);
}
28 Object Oriented Programming
The checked Keyword
In the previous code, because the sum is greater than a byte, this
triggers a runtime exception.
You can also force overflow checking to occur over a block of
code statements:
byte b1 = 100;
byte b2 = 250;
try
{
checked
{
byte sum = (byte)Add(b1, b2);
Console.WriteLine("sum = {0}", sum);
}
}
catch (OverflowException ex)
{
Console.WriteLine(ex.Message);
}
29 Object Oriented Programming
Project-wide Overflow Checking
Enable the /checked flag → all arithmetic operations will be
evaluated for overflow
If overflow has been discovered, you will receive a runtime
exception.
To enable this flag using Visual Studio:
1. Open the project’s property page.
2. Select Advanced from the Build menu.
3. Select the “Check for arithmetic overflow” check box.
30 Object Oriented Programming
Project-wide Overflow Checking
31 Object Oriented Programming
The unchecked Keyword
The /checked flag will evaluate all arithmetic logic.
The unchecked keyword → to disable the throwing of an overflow
exception on a case-by-case basis
Consider the following example:
byte b1 = 100;
byte b2 = 250;
unchecked
{
byte sum = (byte)(b1 + b2);
Console.WriteLine("sum = {0}", sum);
}
Assuming /checked is enabled, this block of code will not trigger a
runtime exception.
32 Object Oriented Programming
Type Conversion
The default behavior of the .NET runtime is to ignore arithmetic
overflow/underflow.
When you want to selectively handle discrete statements, make use
of the checked keyword.
If you want to trap overflow errors throughout your application,
enable the /checked flag.
The unchecked keyword can be used if you have a block of code
where overflow is acceptable (and thus should not trigger a runtime
exception).
33 Object Oriented Programming
Implicitly Typed Variables
So far, we have explicitly specified the data type of each variable:
int myInt = 0;
bool myBool = true;
string myString = "Hello World!";
The C# language provides for implicitly typing of local variables
using the var keyword.
The var keyword → used in place of specifying a specific data type
(such as int, bool, or string)
When you use var keyword, the compiler will automatically
infer the underlying data type based on the initial value.
34 Object Oriented Programming
Implicitly Typed Variables
Consider the following example:
var myInt = 0;
var myBool = true;
var myString = "Hello World!";
In this case, the compiler is able to infer that
myInt is of type System.Int32
myBool is of type System.Boolean
myString is of type System.String
You can determine the data type of an implicitly typed variable:
Console.WriteLine("myInt is a: {0}", myInt.GetType().Name);
Console.WriteLine("myBool is a: {0}", myBool.GetType().Name);
Console.WriteLine("myString is a: {0}", myString.GetType().Name);
35 Object Oriented Programming
Implicitly Typed Variables
Whole numbers → default to integers
Floating-point numbers → default to doubles
You can declare numerics implicitly as well:
var myUInt = 0u;
var myInt = 0;
var myLong = 0L;
var myDouble = 0.5;
var myFloat = 0.5F;
var myDecimal = 0.5M;
You can print out the underlying data types as follows:
Console.WriteLine("myLong is a: {0}", myLong.GetType().Name);
36 Object Oriented Programming
Implicitly Typed Variables
There are some restrictions regarding the use of the var keyword.
Implicit typing applies only to local variables in a method or
property scope.
It is illegal to use the var keyword to define return values,
parameters, or field data of a custom type:
class ThisWillNeverCompile
{
// Error! var cannot be used as field data!
private var myInt = 10;
// Error! var cannot be used as a return value
// or parameter type!
public var MyMethod(var x, var y) { }
}
37 Object Oriented Programming
Implicitly Typed Variables
Implicitly typed variables must be assigned an initial value at the
time of declaration:
// Error! Must assign a value!
var myData;
// Error! Must assign value at exact time of declaration!
var myInt;
myInt = 0;
Implicitly typed variables cannot be assigned initial value of null:
// Error! Can't assign null as initial value!
var myObj = null;
38 Object Oriented Programming
Implicitly Typed Variables
It is permissible to assign the value of an implicitly typed local
variable to the value of other variables:
var myInt = 0;
var anotherInt = myInt;
string myString = "Wake up!";
var myData = myString;
It is permissible to return an implicitly typed variable to the caller:
static int GetAnInt()
{
var retVal = 9;
return retVal;
}
39 Object Oriented Programming
Implicitly Typed Variables
The use of the var keyword is not the same technique used with
scripting languages (such as JavaScript).
Consider the following example:
// The compiler knows "s" is a System.String
var s = "This variable can only hold string data!";
s = "This is fine...";
// Can invoke any member of the underlying type
string upper = s.ToUpper();
// Error! Can't assign numerical data to a string!
s = 44;
Implicit typing of variables results in strongly typed data.
40 Object Oriented Programming
References
Strings and string literals, https://learn.microsoft.com/en-
us/dotnet/csharp/programming-guide/strings/
Using the StringBuilder Class, https://learn.microsoft.com/en-
us/dotnet/standard/base-types/stringbuilder
StringBuilder Class, https://learn.microsoft.com/en-
us/dotnet/api/system.text.stringbuilder
Type Conversion Tables in .NET, https://learn.microsoft.com/en-
us/dotnet/standard/base-types/conversion-tables
checked and unchecked statements, https://learn.microsoft.com/en-
us/dotnet/csharp/language-reference/statements/checked-and-unchecked
Implicitly typed local variables, https://learn.microsoft.com/en-
us/dotnet/csharp/programming-guide/classes-and-structs/implicitly-typed-
local-variables
41 Object Oriented Programming
That’s all for
today!