Download as pdf or txt
Download as pdf or txt
You are on page 1of 49

Object Oriented Programming (C#) (CSE 321)

Lecture 4

C# Classes, Properties,
Indexers and Methods

Prepared by:
Dr. Ahmed Samy Moursi
Computer Science and Engineering Department
https://ahmedhashwa.github.io/

1
Quote of the day (1)

Lecture 4
CSE 321 Object Oriented Programming (C#) 2
Agenda

Lecture 4
CSE 321 Object Oriented Programming (C#) 3
Classes and
Objects
Classes and Objects

Lecture 4
◼ We will build a simple bank-account class called Account to implement
object-oriented programming.
◼ To represent classes graphically we use Unified Modelling Language
(UML)

Account

- name: string

+ SetName (accountName:string)
+ GetName () : string

CSE 321 Object Oriented Programming (C#) 5


Account Class

Lecture 4
class Account
{
private string name; // instance variable

// method that sets the account name in the object


public void SetName(string accountName)
{
name = accountName; // store the account name
}

// method that retrieves the account name from the object


public string GetName()
{
return name; // returns name's value to this method's caller
}
}
What about this keyword?
CSE 321 Object Oriented Programming (C#) 6
Account Class Driver

Lecture 4
class AccountTest
{
static void Main()
{
// create an Account object and assign it to myAccount
Account myAccount = new Account();

// display myAccount's initial name (there isn't one)


Console.WriteLine($"Initial name is: {myAccount.GetName()}");

// prompt for and read the name, then put the name in the object
Console.Write("Enter the name: "); // prompt
string theName = Console.ReadLine(); // read the name
myAccount.SetName(theName); // put theName in the myAccount object

// display the name stored in the myAccount object


Console.WriteLine($"myAccount's name is: {myAccount.GetName()}");
}
}

CSE 321 Object Oriented Programming (C#) 7


Properties
Account Class with Properties

Lecture 4
class Account
{
private string name; // instance variable

// property to get and set the name instance variable


public string Name
{
get // returns the corresponding instance variable's value
{
return name; // returns the value of name to the client code
}
set // assigns a new value to the corresponding instance variable
{
name = value; // value is implicitly declared and initialized
}
}
}
What about expression-bodies properties & access modifiers

CSE 321 Object Oriented Programming (C#) 9


Account Class with Properties Driver

Lecture 4
using System;

class AccountTest
{
static void Main()
{
// create an Account object and assign it to myAccount
Account myAccount = new Account();

// display myAccount's initial name


Console.WriteLine($"Initial name is: {myAccount.Name}");

// prompt for and read the name, then put the name in the object
Console.Write("Please enter the name: "); // prompt
string theName = Console.ReadLine(); // read a line of text
myAccount.Name = theName; // put theName in myAccount's Name

// display the name stored in object myAccount


Console.WriteLine($"myAccount's name is: {myAccount.Name}");
}
}

CSE 321 Object Oriented Programming (C#) 10


Account Class with Auto Properties

Lecture 4
class Account
{
public string Name { get; set; } // auto-implemented property

// constructor sets the Name property to parameter accountName's value


public Account(string accountName) // constructor name is class name
{
Name = accountName;
}
}

CSE 321 Object Oriented Programming (C#) 11


Account Class with Auto Properties Driver

Lecture 4
using System;
class AccountTest
{
static void Main()
{
// create two Account objects
Account account1 = new Account("Jane Green");
Account account2 = new Account("John Blue");

// display initial value of name for each Account


Console.WriteLine($"account1 name is: {account1.Name}");
Console.WriteLine($"account2 name is: {account2.Name}");
}
}
CSE 321 Object Oriented Programming (C#) 12
Account Class Required Property (C# 11)

Lecture 4
namespace L4_AccountPropertiesRequired;

public class Account


{
public required string Name { get; set; } // auto-implemented property
public long AccountNumber { get; init; } = Random.Shared.NextInt64(); // auto-implemented property
}

CSE 321 Object Oriented Programming (C#) 13


Lecture 4
Account Class Required Property Driver (C#11)
using L4_AccountPropertiesRequired;

// create two Account objects


Account account1 = new()
{
Name = "Jane Green", //must provide Name
AccountNumber = 9931287986869870L
};
var account2 = new Account
{
Name = "John Blue", //must provide Name
};

// display initial value of name for each Account


Console.WriteLine(
$@"account1 {nameof(Account.Name)} is: {account1.Name}
{nameof(account1.AccountNumber)} is: {account1.AccountNumber}");
Console.WriteLine($"account2 {nameof(Account.Name)} is: {account2.Name} " +
$"& {nameof(account1.AccountNumber)} is: {account2.AccountNumber}");
account1.Name = "Will Green";
//account2.AccountNumber = 2340970L; // compile-time error not allowed init-only

CSE 321 Object Oriented Programming (C#) 14


Notes on init-only properties

Lecture 4
◼ Init-only properties cannot even be set from inside their class, except via their
property initializer, the constructor, or another init-only accessor.
◼ The alternative to init-only properties is to have read-only properties that you

populate via a constructor:


public class Note
{
public int Pitch { get; }
public int Duration { get; }
public Note (int pitch, int duration )
{
Pitch = pitch; Duration = duration;
}
}

CSE 321 Object Oriented Programming (C#) 15


Notes on properties

Lecture 4
◼ C# property accessors internally compile to methods called get_XXX and set_XXX:
public decimal get_CurrentPrice {...}
public void set_CurrentPrice (decimal value) {...}

CSE 321 Object Oriented Programming (C#) 16


Quote of the day (2)

Lecture 4
CSE 321 Object Oriented Programming (C#) 17
Indexers
Indexers

Lecture 4
◼ Indexers provide a natural syntax for accessing elements in a class or struct that
encapsulate a list or dictionary of values. Indexers are similar to properties but are
accessed via an index argument rather than a property name.
◼ The syntax for using indexers is like that for using arrays, except that the index
argument(s) can be of any type(s).

public partial class Sentence


{
string[] words = "The quick brown fox".Split();
}

CSE 321 Object Oriented Programming (C#) 19


Indexer Sample partial class

Lecture 4
public partial class Sentence
{
public string this[int wordNum] // indexer
{
get => words[wordNum];
set => words[wordNum] = value;
}
/// <summary>
/// Get the index of <see cref="word"/> in the array
/// </summary>
/// <param name="word">The word to look for the index of in the array of words</param>
public int this[string word] => Array.IndexOf(words, word);
/// <summary>
/// Test if first and second are consecutive in the array
/// </summary>
/// <param name="first">First element of the array</param>
/// <param name="second">Second element of the array</param>
public bool this[string first, string second] => Array.IndexOf(words, first) + 1 == Array.IndexOf(words, second);

public string this[Index index] => words[index];


public string[] this[Range range] => words[range];
}

CSE 321 Object Oriented Programming (C#) 20


Indexer Driver Class

Lecture 4
// See https://aka.ms/new-console-template for more information

Sentence s = new ();


Console.WriteLine (s[3]); // fox
s[3] = "kangaroo";
Console.WriteLine (s[3]); // kangaroo
Console.WriteLine (s [^1]); // fox
var firstTwoWords = s [..2]; // (The, quick)
foreach(var word in firstTwoWords)
Console.WriteLine(word);
Console.WriteLine(s["brown"]);
Console.WriteLine(s["quick","brown"]);

CSE 321 Object Oriented Programming (C#) 21


Quote of the day (3)

Lecture 4
CSE 321 Object Oriented Programming (C#) 22
Quick review questions (3 min)

Lecture 4
CSE 321 Object Oriented Programming (C#) 23
Methods
Methods

Lecture 4
◼ A method performs an action in a series of statements.
◼ A method can receive input data from the caller by specifying parameters, and
output data back to the caller by specifying a return type.
◼ A method can specify a void return type, indicating that it doesn’t return any value
to its caller.
◼ A method can also output data back to the caller via ref/out parameters.
◼ A method’s signature must be unique within the type. A method’s signature
comprises its name and parameter types in order (but not the parameter names,
nor the return type).

CSE 321 Object Oriented Programming (C#) 25


Expression-bodied methods

Lecture 4
◼ A method that comprises a single expression, such as
int Foo (int x) { return x * 2; }
◼ can be written more tersely as an expression-bodied method. A fat arrow replaces
the braces and return keyword:
int Foo (int x) => x * 2;
◼ Expression-bodied functions can also have a void return type:
void Foo (int x) => Console.WriteLine (x);

CSE 321 Object Oriented Programming (C#) 26


Local methods

Lecture 4
◼ You can define a method within another method:
void WriteCubes()
{
Console.WriteLine (Cube (3));
Console.WriteLine (Cube (4));
Console.WriteLine (Cube (5));
int Cube (int value) => value * value * value;
}
◼ Adding the static modifier to a local method (from C# 8) prevents it from seeing the

local variables and parameters of the enclosing method.

CSE 321 Object Oriented Programming (C#) 27


Methods Parameters

Lecture 4
◼ A method may have a sequence of parameters. Parameters define the set of
arguments that must be provided for that method.

Parameter modifier Passed by Variable must be


definitely assigned

(None) Value Going in

ref Reference Going in

in Reference(read-only) Going in

out Reference Going out

CSE 321 Object Oriented Programming (C#) 28


Passing arguments by value

Lecture 4
◼ By default, arguments in C# are passed by value, which is by far the
most common case.
◼ This means that a copy of the value is created when passed to the

method.
var x = 8;
Foo (x); // Make a copy of x
Console.WriteLine (x); // x will still be 8
static void Foo (int p)
{
p = p + 1; // Increment p by 1
Console.WriteLine (p); // Write p to screen
}

◼ Assigning p a new value does not change the contents of x, because p and x reside
in different memory locations.

CSE 321 Object Oriented Programming (C#) 29


Lecture 4
Passing arguments by value (reference types)
◼ Passing a reference-type argument by value copies the reference but
not the object.
◼ In the following example, Foo sees the same StringBuilder object we
instantiated (sb) but has an independent reference to it. In other words,
sb and fooSB are separate variables that reference the same
var sb = new StringBuilder();
Bar (sb);
Console.WriteLine (sb.ToString()); // test
static void Bar (StringBuilder fooSB)
{
fooSB.Append ("test");
fooSB = null;
}

◼ Because fooSB is a copy of a reference, setting it to null doesn’t make


sb null. (If, however, fooSB was declared and called with the ref
modifier, sb would become null.)

CSE 321 Object Oriented Programming (C#) 30


The ref modifier (value types)

Lecture 4
◼ To pass by reference, C# provides the ref parameter modifier. In the
following example, p and x refer to the same memory locations:
int x = 8;
Foo (ref x); // Ask Foo to deal directly with x
Console.WriteLine (x); // x is now 9
static void Foo (ref int p)
{
p += 1; // Increment p by 1
Console.WriteLine (p); // Write p to screen
}

CSE 321 Object Oriented Programming (C#) 31


The ref modifier (reference types)

Lecture 4
◼ The ref modifier is essential in implementing a swap method.

string x = "Penn";
string y = "Teller";
Swap (ref x, ref y);
Console.WriteLine (x); // Teller
Console.WriteLine (y); // Penn
static void Swap (ref string a, ref string b)
{
string temp = a;
a = b;
b = temp;
}
◼ A parameter can be passed by reference or by value, regardless of whether the

parameter type is a reference type or a value type.

CSE 321 Object Oriented Programming (C#) 32


The out modifier

Lecture 4
◼ An out argument is like a ref argument except for the following:
◼ It need not be assigned before going into the function.

◼ It must be assigned before it comes out of the function.

◼ Like a ref parameter, an out parameter is passed by reference.


◼ The out modifier is most commonly used to get multiple return values back from a
◼ method; for example:
string a, b;
Split ("Stevie Ray Vaughn", out a, out b);
Console.WriteLine (a); // Stevie Ray
Console.WriteLine (b); // Vaughn
void Split (string name, out string firstNames, out string lastName)
{
int i = name.LastIndexOf (' ');
firstNames = name[..i];
lastName = name[(i + 1)..];
}

CSE 321 Object Oriented Programming (C#) 33


Out variables and discards

Lecture 4
◼ You can declare variables on the fly when calling methods with out parameters. We
can replace the first two lines in our preceding example with this:
Split ("Stevie Ray Vaughan", out string a, out string b);
◼ When calling methods with multiple out parameters, sometimes you’re not
interested in receiving values from all the parameters. In such cases, you can
“discard” the ones in which you’re uninterested by using an underscore:
Split ("Stevie Ray Vaughan", out string a, out _); // Discard 2nd param
Console.WriteLine (a);
◼ In this case, the compiler treats the underscore as a special symbol, called a discard.
◼ You can include multiple discards in a single call. Assuming SomeBigMethod has
been defined with seven out parameters, we can ignore all but the fourth, as
follows:
SomeBigMethod (out _, out _, out _, out int x, out _, out _, out _);
◼ For backward compatibility, this language feature will not take effect if a real
underscore variable is in scope:
string _;
Split ("Stevie Ray Vaughan", out string a, out _);
Console.WriteLine (_); // Vaughan
CSE 321 Object Oriented Programming (C#) 34
The in modifier

Lecture 4
◼ An in parameter is similar to a ref parameter except that the argument’s value
cannot be modified by the method (doing so generates a compile-time error).
◼ This modifier is most useful when passing a large value type to the method because
it allows the compiler to avoid the overhead of copying the argument prior to
passing it in while still protecting the original value from modification.
◼ Overloading solely on the presence of in is permitted:
void Foo ( SomeBigStruct a) { ... }
void Foo (in SomeBigStruct a) { ... }
◼ To call the second overload, the caller must use the in modifier:
SomeBigStruct x = ...;
Foo (x); // Calls the first overload
Foo (in x); // Calls the second overload
◼ When there’s no ambiguity,
void Bar (in SomeBigStruct a) { ... }
◼ use of the in modifier is optional for the caller:
Bar (x); // OK (calls the 'in' overload)
Bar (in x); // OK (calls the 'in' overload)

CSE 321 Object Oriented Programming (C#) 35


Quote of the day (4)

Lecture 4
CSE 321 Object Oriented Programming (C#) 36
The params modifier

Lecture 4
◼ The params modifier, if applied to the last parameter of a method, allows the
method to accept any number of arguments of a particular type.
◼ The parameter type must be declared as an (single-dimensional) array, as shown in

the following example:


int total = Sum (1, 2, 3, 4);
Console.WriteLine (total); // 10
// The call to Sum above is equivalent to:
int total2 = Sum (new int[] { 1, 2, 3, 4 });
int Sum (params int[] ints)
{
int sum = 0;
foreach (var t in ints)
sum += t; // Increase sum by t

return sum;
}
◼ If there are zero arguments in the params position, a zero-length array is created.

CSE 321 Object Oriented Programming (C#) 37


Default Values

Lecture 4
◼ All type instances have a default value. The default value for the predefined types is
the result of a bitwise zeroing of memory:
◼ Reference types (and nullable value types) have default value of null
◼ Numeric and enum types have default value of 0
◼ char type has default value of '\0’
◼ bool type has default value of false
◼ You can obtain the default value for any type via the default keyword:
Console.WriteLine (default (decimal)); // 0
◼ You can optionally omit the type when it can be inferred:
decimal d = default;
◼ The default value in a custom value type (i.e., struct) is the same as the default
value for each field defined by the custom type.

CSE 321 Object Oriented Programming (C#) 38


Optional parameters

Lecture 4
◼ Methods, constructors, and indexers can declare optional parameters.
◼ A parameter is optional if it specifies a default value in its declaration:
void Foo (int x = 23) { Console.WriteLine (x); }
◼ You can omit optional parameters when calling the method:
Foo(); // 23
◼ The default argument of 23 is actually passed to the optional parameter x—the
compiler bakes the value 23 into the compiled code at the calling side. The
preceding call to Foo is semantically identical to
Foo (23);
◼ The default value of an optional parameter must be specified by a constant
expression, a parameterless constructor of a value type, or a default expression.
◼ Optional parameters cannot be marked with ref or out.

CSE 321 Object Oriented Programming (C#) 39


Optional parameters

Lecture 4
◼ Mandatory parameters must occur before optional parameters in both the method
declaration and the method call (the exception is with params arguments, which
still always come last).
◼ In the following example, the explicit value of 1 is passed to x, and the default value
of 0 is passed to y:
Foo (1); // 1, 0
void Foo (int x = 0, int y = 0) { Console.WriteLine (x + ", " + y); }
◼ You can do the converse (pass a default value to x and an explicit value to y) by
combining optional parameters with named arguments.

CSE 321 Object Oriented Programming (C#) 40


Named arguments

Lecture 4
◼ Rather than identifying an argument by position, you can identify an argument by
name:
Foo (x:1, y:2); // 1, 2
void Foo (int x, int y) { Console.WriteLine (x + ", " + y); }
◼ Named arguments can occur in any order. The following calls to Foo are
semantically identical:
Foo (x:1, y:2);
Foo (y:2, x:1);
◼ A subtle difference is that argument expressions are evaluated in the order in which
they appear at the calling site.
◼ In general, this makes a difference only with interdependent side-effecting
expressions such as the following, which writes 0, 1:
int a = 0;
Foo (y: ++a, x: --a); // ++a is evaluated first
◼ Of course, you would almost certainly avoid writing such code in practice!

CSE 321 Object Oriented Programming (C#) 41


Named arguments

Lecture 4
◼ You can mix named and positional arguments:
Foo (1, y:2);
◼ However, there is a restriction: positional arguments must come before named
arguments unless they are used in the correct position. So, you could call Foo like
this:
Foo (x:1, 2); // OK. Arguments in the declared positions
◼ But not like this:
Foo (y:2, 1); // Compile-time error. y isn't in the first position
◼ Named arguments are particularly useful in conjunction with optional parameters.
For instance, consider the following method:
void Bar (int a = 0, int b = 0, int c = 0, int d = 0) { ... }
◼ You can call this supplying only a value for d, as follows:
Bar (d:3);

CSE 321 Object Oriented Programming (C#) 42


Ref Locals

Lecture 4
◼ A somewhat esoteric feature of C# is that you can define a local variable that
references an element in an array or field in an object (from C# 7):
int[] numbers = { 0, 1, 2, 3, 4 };
ref int numRef = ref numbers [2];
◼ In this example, numRef is a reference to numbers[2]. When we modify numRef, we

modify the array element:


numRef *= 10;
Console.WriteLine (numRef); // 20
Console.WriteLine (numbers [2]); // 20
◼ The target for a ref local must be an array element, field, or local variable; it cannot

be a property .
◼ Ref locals are intended for specialized micro-optimization scenarios and are

typically used in conjunction with ref returns.

CSE 321 Object Oriented Programming (C#) 43


Ref Returns

Lecture 4
◼ You can return a ref local from a method. This is called a ref return:
class Program
{
static string x = "Old Value";
static ref string GetX() => ref x; // This method returns a ref
static void Main()
{
ref string xRef = ref GetX(); // Assign result to a ref local
xRef = "New Value";
Console.WriteLine (x); // New Value
}
}
◼ If you omit the ref modifier on the calling side, it reverts to returning an ordinary
value:
string localX = GetX(); // Legal: localX is an ordinary non-ref variable.

CSE 321 Object Oriented Programming (C#) 44


Ref Returns

Lecture 4
◼ You also can use ref returns when defining a property or indexer:
static ref string Prop => ref x;
◼ Such a property is implicitly writable, despite there being no set accessor:
Prop = "New Value";
◼ You can prevent such modification by using ref readonly:
static ref readonly string Prop => ref x;

CSE 321 Object Oriented Programming (C#) 45


Quote of the day (5)

Lecture 4
CSE 321 Object Oriented Programming (C#) 46
Quick review on methods and others (5min)

Lecture 4
CSE 321 Object Oriented Programming (C#) 47
References
References

Lecture 4
◼ C# How to Program : Chapter 4
◼ required modifier - C# Reference - C# | Microsoft Learn
◼ C# 10 in a Nutshell Chapter 3 : Methods.
◼ C# 10 in a Nutshell Chapter 3 : Indexers.
◼ C# 10 in a Nutshell Chapter 3 : Properties.
◼ C# 10 in a Nutshell Chapter 2 : Variables and Parameters.

CSE 321 Object Oriented Programming (C#) 49

You might also like