.NET Types Hierarchy, Cloning, Comparing, Value and Reference Types, Parameters Passing Svetlin Nakov Telerik Software Academy academy.telerik.com Technical.

Slides:



Advertisements
Similar presentations
Windows Basic and Dynamic Disk Borislav Varadinov Telerik Software Academy academy.telerik.com System Administrator Marian Marinov CEO of 1H Ltd.
Advertisements

HTML Forms, GET, POST Methods Tran Anh Tuan Edit from Telerik Academy
Make swiftly iOS development Telerik Academy Telerik Academy Plus.
Amazon S 3, App Engine Blobstore, Google Cloud Storage, Azure Blobs Svetlin Nakov Telerik Software Academy academy.telerik.com.
RPN and Shunting-yard algorithm Ivaylo Kenov Telerik Software Academy academy.telerik.com Technical Assistant
Shortest paths in edge-weighted digraph Krasin Georgiev Technical University of Sofia g.krasin at gmail com Assistant Professor.
Telerik Software Academy Telerik School Academy.
Asynchronous Programming with C# and WinRT
Touch and Gestures with Xamarin Forms
Character sequences, C-strings and the C++ String class, Working with Strings Learning & Development Team Telerik Software Academy.
Done already for your convenience! Telerik School Academy Unity 2D Game Development.
Processing Sequences of Elements Telerik School Academy C# Fundamentals – Part 1.
C# Fundamentals – Part I
The Business Plan and the Business Model Margarita Antonova Volunteer Telerik Academy academy.telerik.com Business System Analyst Telerik Corporation.
What are ADTs, STL Intro, vector, list, queue, stack Learning & Development Team Telerik Software Academy.
Making JavaScript code by template! Learning & Development Team Telerik Software Academy.
Svetlin Nakov Telerik Software Academy academy.telerik.com Manager Technical Training Who, What, Why?
Access to known folders, using pickers, writing to and reading from files, caching files for future access George Georgiev Telerik Software Academy academy.telerik.com.
Processing Matrices and Multidimensional Tables Svetlin Nakov Telerik Software Academy academy.telerik.com Technical Trainer
Learning & Development Telerik Software Academy.
Reading and Writing Text Files Svetlin Nakov Telerik Software Academy academy.telerik.com Technical Trainer
Telerik Software Academy ASP.NET Web Forms.
Classical OOP in JavaScript Classes and stuff Telerik Software Academy
Optimization problems, Greedy Algorithms, Optimal Substructure and Greedy choice Learning & Development Team Telerik Software.
Using Selenium for Mobile Web Testing Powered by KendoUI Telerik QA Academy Atanas Georgiev Senior QA Engineer KendoUI Team.
NoSQL Concepts, Redis, MongoDB, CouchDB Svetlin Nakov Telerik Software Academy academy.telerik.com Manager Technical Training
New features: classes, generators, iterators, etc. Telerik Academy Plus JavaScript.Next.
Throwing and Catching Exceptions Tran Anh Tuan Edit from Telerik Software Academy
Handling Errors during the Program Execution Svetlin Nakov Telerik Software Academy academy.telerik.com Technical Trainer
Loops, Conditional Statements, Functions Tran Anh Tuan Edit from Telerik Academy
Common Type System .NET Types Hierarchy, Cloning, Comparing, Collection Iterators, Value and Reference Types SoftUni Team Technical Trainers Software.
Concerned with communication (interaction) between the objects Telerik Software Academy High-Quality Code.
Private/Public fields, Module, Revealing Module Learning & Development Team Telerik Software Academy.
Building Data-Driven ASP.NET Web Forms Apps Telerik Software Academy ASP.NET Web Forms.
Course Introduction Svetlin Nakov Telerik Software Academy academy.telerik.com Manager Technical Training
Telerik Software Academy End-to-end JavaScript Applications.
General and reusable solutions to common problems in software design Vasil Dininski Telerik Software Academy academy.telerik.com Intern at Telerik Academy.
Planning and Tracking Software Quality Yordan Dimitrov Telerik Corporation Team Leader, Team Pulse, Team Leader, Team Pulse, Telerik Corporation,
What you need to know Ivaylo Kenov Telerik Corporation Telerik Academy Student.
Data binding concepts, Bindings in WinJS George Georgiev Telerik Software Academy academy.telerik.com Technical Trainer itgeorge.net.
Pavel Kolev Telerik Software Academy Senior.Net Developer and Trainer
Objects, Properties, Primitive and Reference Types Learning & Development Team Telerik Software Academy.
When and How to Refactor? Refactoring Patterns Alexander Vakrilov Telerik Corporation Senior Developer and Team Leader.
Free Training and Job for Software Engineers Svetlin Nakov, PhD Manager Technical Training Telerik Corp. Telerik Software Academy.
Access to known folders, using pickers, writing to and reading from files, caching files for future access George Georgiev Telerik Software Academy academy.telerik.com.
Doing the Canvas the "easy way"! Learning & Development Telerik Software Academy.
Creating and Running Your First C# Program Svetlin Nakov Telerik Software Academy academy.telerik.com Manager Technical Training
Subroutines in Computer Programming Telerik School Academy C# Fundamentals – Part 1.
Common Type System.NET Types Hierarchy, Cloning, Comparing, Collection Iterators, Value and Reference Types Svetlin Nakov Technical Trainer
Correctly Formatting the Source Code Nikolay Kostov Telerik Software Academy academy.telerik.com Senior Software Developer and Technical Trainer
Data Types, Primitive Types in C++, Variables – Declaration, Initialization, Scope Telerik Software Academy academy.telerik.com Learning and Development.
The past, the present, the future Learning & Development Team Telerik Software Academy.
Using the Standard.NET Framework Classes Telerik Software Academy C# Fundamentals – Part 2.
Learn to Design Error Steady Code Svetlin Nakov Telerik Software Academy academy.telerik.com Technical Trainer
Connecting, Queries, Best Practices Tran Anh Tuan Edit from Telerik Software Academy
Processing Sequences of Elements Telerik Software Academy C# Fundamentals – Part 2.
Telerik JavaScript Framework Telerik Software Academy Hybrid Mobile Applications.
Telerik Software Academy Databases.
Things start to get serious Telerik Software Academy JavaScript OOP.
Learning & Development Mobile apps for iPhone & iPad.
Processing Matrices and Multidimensional Tables Telerik Software Academy C# Fundamentals – Part 2.
Nikolay Kostov Telerik Software Academy academy.telerik.com Team Lead, Senior Developer and Trainer
Functions and Function Expressions Closures, Function Scope, Nested Functions Telerik Software Academy
Implementing Control Logic in C# Svetlin Nakov Telerik Software Academy academy.telerik.com Manager Technical trainer
Inheritance, Abstraction, Encapsulation, Polymorphism Telerik Software Academy Mobile apps for iPhone & iPad.
Mocking tools for easier unit testing Telerik Software Academy High Quality Code.
Creating and Initializing Arrays, Accessing Elements, Multiple Dimensions Learning & Development Team Telerik Software Academy.
What why and how? Telerik School Academy Unity 2D Game Development.
Windows Security Model Borislav Varadinov Telerik Software Academy academy.telerik.com System Administrator
Definition, Constructors, Methods, Access Modifiers, Static/Instance members, Learning & Development Team Telerik Software Academy.
Presentation transcript:

.NET Types Hierarchy, Cloning, Comparing, Value and Reference Types, Parameters Passing Svetlin Nakov Telerik Software Academy academy.telerik.com Technical Trainer

 What is Common Type System (CTS)?  Types Hierarchy  The System.Object type  Overriding the Virtual Methods in System.Object  Operators is and as  Object Cloning  ICloneable Interface  The IComparable Interface 2

 The IEnumerable interface  Value Types and Reference Types  Boxing and Unboxing  Passing Parameters  Input, Output and Reference Passing 3

What is Common Type System (CTS)?

What is CTS?What is CTS? .NET Common Type System (CTS)  Defines CLR supported  Data types  Operations performed on them  Extends the compatibility between different.NET languages  Supports two types of data  Value types  Reference types  All data types are inheritors of System.Object 5

.NET CTS Types Hierarchy.NET CTS Types Hierarchy 6

The System.Object TypeThe System.Object Type

System.Object TypeSystem.Object Type  Base class for each.NET type  Inherited by default when a new type is defined  Important virtual methods:  Equals() – comparison with other object  ToString() – represents the object as a string  GetHashCode() – evaluates the hash code (used with hash-tables)  Finalize() – used for clean up purposes when an object is disposed 8

Overriding the Virtual Methods in System.Object

Overriding System.Object's Virtual Methods  By default the operator == calls the ReferenceEquals() method  Compares the addresses for reference types  Or the binary representation for value types  The methods Equals(), GetHashCode() should be defined at the same time  The same applies for the operators == and !=  You can o verride Equals() and use its implementation for == and !=  You can override Equals() and use its implementation for == and != 10

Overriding System.Object Methods – Example 11 public class Student { public string Name { get; set; } public string Name { get; set; } public int Age { get; set; } public int Age { get; set; } public override bool Equals(object param) public override bool Equals(object param) { // If the cast is invalid, the result will be null // If the cast is invalid, the result will be null Student student = param as Student; Student student = param as Student; // Check if we have valid not null Student object // Check if we have valid not null Student object if (student == null) if (student == null) return false; return false; // Compare the reference type member fields // Compare the reference type member fields if (! Object.Equals(this.Name, student.Name)) if (! Object.Equals(this.Name, student.Name)) return false; return false; // Compare the value type member fields // Compare the value type member fields if (this.Age != student.Age) if (this.Age != student.Age) return false; return false; return true; return true; } // the example continues

Overriding System.Object Methods – Example (2) 12 public static bool operator == (Student student1, public static bool operator == (Student student1, Student student2) Student student2) { return Student.Equals(student1, student2); return Student.Equals(student1, student2); } public static bool operator !=(Student student1, public static bool operator !=(Student student1, Student student2) Student student2) { return !(Student.Equals(student1, student2)); return !(Student.Equals(student1, student2)); } public override int GetHashCode() public override int GetHashCode() { return Name.GetHashCode() ^ Age.GetHashCode(); return Name.GetHashCode() ^ Age.GetHashCode(); }}

Overriding the Virtual Methods in System.Object Live Demo

More About System.ObjectMore About System.Object  The System.Object type has some other methods, which are inherited by all.NET types:  GetType()  Returns type's metadata as a System.Type  MemberwiseClone()  Copies the binary representation of the variable into a new variable (shallow clone)  ReferenceEquals()  Compares if two object have the same reference 14

is and as operators

Type Operators in C#Type Operators in C#  The is operator  Checks if an object an is instance of some type  Polymorphic operation  5 is Int32  5 is object  5 is IComparable  5 is IComparable  The as operator  Casts a reference type to another reference type  Returns null value if it fails  E.g. if the types are incompatible 16

class Base { } class Derived : Base { } class TestOperatorsIsAndAs { static void Main() static void Main() { Object objBase = new Base(); Object objBase = new Base(); if (objBase is Base) if (objBase is Base) Console.WriteLine("objBase is Base"); Console.WriteLine("objBase is Base"); // Result: objBase is Base // Result: objBase is Base if (! (objBase is Derived)) if (! (objBase is Derived)) Console.WriteLine("objBase is not Derived"); Console.WriteLine("objBase is not Derived"); // Result : objBase is not Derived // Result : objBase is not Derived if (objBase is System.Object) if (objBase is System.Object) Console.WriteLine("objBase is System.Object"); Console.WriteLine("objBase is System.Object"); // Result : objBase is System.Object // Result : objBase is System.Object // the example continues Operators is and as – ExampleOperators is and as – Example 17

Operators is and as – Example (2)Operators is and as – Example (2) 18 Base b = objBase as Base; Base b = objBase as Base; Console.WriteLine("b = {0}", b); Console.WriteLine("b = {0}", b); // Result: b = Base // Result: b = Base Derived d = objBase as Derived; Derived d = objBase as Derived; if (d == null) if (d == null) Console.WriteLine("d is null"); Console.WriteLine("d is null"); // Result: d is null // Result: d is null Object o = objBase as Object; Object o = objBase as Object; Console.WriteLine("o = {0}", o); Console.WriteLine("o = {0}", o); // Result: o = Base // Result: o = Base Derived der = new Derived(); Derived der = new Derived(); Base bas = der as Base; Base bas = der as Base; Console.WriteLine("bas = {0}", bas); Console.WriteLine("bas = {0}", bas); // Result: bas = Derived // Result: bas = Derived }}

Operators is and as Live Demo

Object CloningObject Cloning

 In programming cloning an object means to create an identical copy of certain object  Shallow cloning (shallow copy)  Uses the protected MemberwiseClone() method  Copies the value types bit by bit (binary)  Copies only the addresses of the reference types  Deep cloning (deep copy)  Recursively copies all member data  Implemented manually by the programmer 21

Object Cloning (2)Object Cloning (2)  Types which allow cloning implement the ICloneable interface  The Clone() method of the ICloneable  The only method of the interface  Returns an identical copy of the object  Returns object  must be casted later  You decide whether to create a deep or shallow copy or something between 22

class LinkedList : ICloneable { public T Value { get; set; } public T Value { get; set; } public LinkedList NextNode { get; private set; } public LinkedList NextNode { get; private set; } public LinkedList(T value, public LinkedList(T value, LinkedList nextNode = null) LinkedList nextNode = null) { this.Value = value; this.Value = value; this.NextNode = nextNode; this.NextNode = nextNode; } object ICloneable.Clone() // Implicit implementation object ICloneable.Clone() // Implicit implementation { return this.Clone(); return this.Clone(); } // the example continues Object Cloning – ExampleObject Cloning – Example 23

24 public LinkedList Clone() // our method Clone() { // Copy the first element // Copy the first element LinkedList original = this; LinkedList original = this; T valueOriginal = original.Value; T valueOriginal = original.Value; LinkedList result = new LinkedList (valueOriginal); LinkedList result = new LinkedList (valueOriginal); LinkedList copy = result; LinkedList copy = result; original = original.NextNode; original = original.NextNode; // Copy the rest of the elements // Copy the rest of the elements while (original != null) while (original != null) { valueOriginal = original.Value; valueOriginal = original.Value; copy.NextNode = new LinkedList (valueOriginal); copy.NextNode = new LinkedList (valueOriginal); original = original.NextNode; original = original.NextNode; copy = copy.NextNode; copy = copy.NextNode; } return result; return result;}

Deep and Shallow Object CloningDeep and Shallow Object Cloning Live Demo

The Interface IComparable The Interface IComparable

IComparable InterfaceIComparable Interface  The System.IComparable interface  Implemented by the types, which can be compared (ordered in increasing order)  The CompareTo(T) method defines the comparison. It returns:  Number < 0 – if the passed object is bigger than the this instance  Number = 0 – if the passed object is equal to the this instance  Number > 0 – if the passed object is smaller than the this instance 27

IComparable – ExampleIComparable – Example 28 class Point : IComparable class Point : IComparable { public int X { get; set; } public int X { get; set; } public int Y { get; set; } public int Y { get; set; } public int CompareTo(Point otherPoint) public int CompareTo(Point otherPoint) { if (this.X != otherPoint.X) if (this.X != otherPoint.X) { return (this.X - otherPoint.X); return (this.X - otherPoint.X); } if (this.Y != otherPoint.Y) if (this.Y != otherPoint.Y) { return (this.Y - otherPoint); return (this.Y - otherPoint); } return 0; return 0; }}

Implementing IComparable Implementing IComparable Live Demo

The IEnumerable Interface

 The IEnumerable interface provides collection classes with foreach traversal  It consists of 4 interfaces: IEnumerable, IEnumerable, IEnumerator, IEnumerator 31 public interface IEnumerable : IEnumerable { IEnumerator GetEnumerator(); IEnumerator GetEnumerator();} // Non-generic version (compatible with.NET 1.1) public interface IEnumerable : IEnumerable { IEnumerator GetEnumerator(); IEnumerator GetEnumerator();}

 The IEnumerator interface provides sequential read-only, forward-only iterator 32 public interface IEnumerator : IEnumerator { bool MoveNext(); bool MoveNext(); void Reset(); void Reset(); T Current { get; } T Current { get; }} public interface IEnumerator { bool MoveNext(); bool MoveNext(); void Reset(); void Reset(); object Current { get; } object Current { get; }}

 The yield return construct in C# simplifies the IEnumerator implementations  When a yield return statement is reached  The expression is returned, and the current location in code is retained (for later use) 33 public IEnumerator GetEnumerator() { for (int i=100; i<200; i++) for (int i=100; i<200; i++) { yield return i; yield return i; }}

Implementing IEnumerable Implementing IEnumerable Live Demo

 Store their values in the stack  Can not hold null value  Destroyed when the given variable goes out of scope  When a method is called they are:  Passed by value  Stored in the stack (copied) 36

 Inherit System.ValueType  Value types are:  Primitive types  int, char  float, bool  Others  Structures  Enumerations (enumerable types) 37

 Implemented as type-safe pointers to objects  Stored in the dynamic memory  When a method is called they are passed by reference (by their address)  Automatically destroyed by the CLR Garbage Collector, when they are out of scope or they are not in use  Can hold null value 39

 It is possible for many variables to point to one and the same reference type object  Referent objects are:  System.Object, System.String  Classes and interfaces  Arrays  Delegates  Pointers 40

Assigning, Memory Location and Values

 Value Types  When assigning value types, their value is copied to the variable  Reference Types  When assigning referent type, only the reference (address) is copied and the objects stays the same 42

 The memory location for value types is the program execution stack  The memory location for reference types is the dynamic memory  Also called managed heap 43

 Value types can not take null as a value, because they are not pointers  Value types inherit System.ValueType  Reference types inherit System.Object  Value type variables can be stored in reference types with the boxing technique 44

45 class RefClass { public int value; } // Reference type struct ValStruct { public int value; } // Value type class TestValueAndReferenceTypes { static void Main() static void Main() { RefClass refExample = new RefClass(); RefClass refExample = new RefClass(); refExample.value = 100; refExample.value = 100; RefClass refExample2 = refExample; RefClass refExample2 = refExample; refExample2.value = 200; refExample2.value = 200; Console.WriteLine(refExample.value); // Prints 200 Console.WriteLine(refExample.value); // Prints 200 ValStruct valExample = new ValStruct(); ValStruct valExample = new ValStruct(); valExample.value = 100; valExample.value = 100; ValStruct valExample2 = valExample; ValStruct valExample2 = valExample; valExample2.value = 200; valExample2.value = 200; Console.WriteLine(valExample.value); // Prints 100 Console.WriteLine(valExample.value); // Prints 100 }}

46 Stack for program execution (end of stack) (free stack memory) struct2 struct1 class2 class1 (stack beginning) Variable... 0x x0012F x0012F678 0x04A41A44 0x0012F67C 0x04A41A44 0x0012F ValueAddress Dynamic memory (managed heap) 200 0x04A41A ValueAddress

Live Demo

 Value types can be stored in reference types  If needed CLR boxes and unboxes value types  Boxing is operation, that converts a value type to a reference one  Unboxing is the opposite operation  Converts boxed value to ordinary value type 49

1. Allocates dynamic memory for the creation of the object 2. Copies the contents of the variable from the stack to the allocated dynamic memory 3. Returns a reference to the created object in the dynamic memory 4. The original type is memorized 5. The dynamic memory contains information, that the object reference holds boxed object 50

1. If the reference is null a NullReferenceException is thrown 2. If the reference does not point to a valid boxed value an InvalidCastException is thrown 3. The value is pulled from the heap and is stored into the stack 51

52 i=5(value-type variable in the stack) object obj = i; 5 (boxing) obj (boxedvalue-typevariable in the heap) in the heap) (unboxing) i2 = (int) obj; i2=5(value-type variable in the stack) StackHeap int i=5; int i2;

53 using System; class TestBoxingUnboxing { static void Main() static void Main() { int value1 = 1; int value1 = 1; object obj = value1; // boxing performed object obj = value1; // boxing performed value1 = 12345; // only stack value is changed value1 = 12345; // only stack value is changed int value2 = (int)obj; // unboxing performed int value2 = (int)obj; // unboxing performed Console.WriteLine(value2); // prints 1 Console.WriteLine(value2); // prints 1 long value3 = (long) (int) obj; // unboxing long value3 = (long) (int) obj; // unboxing long value4 = (long) obj; // InvalidCastException long value4 = (long) obj; // InvalidCastException }}

Live Demo

55 interface IMovable { void Move(int x, int y) void Move(int x, int y)} // Very bad practice! Structures should // contain no logic, but only data! struct Point : IMovable { public int x, y; public int x, y; public void Move(int x, int y) public void Move(int x, int y) { this.x += x; this.x += x; this.y += y; this.y += y; }}

Live Demo

ref and out Keywords

 Parameters can be passed in several ways to the methods:  in (default)  Passing value for value types  Passing heap address for reference types  out  Passed by stack address for both value types and reference types  The initialization can be done by the called method 58

 Parameters can be passed in several ways to the methods:  ref  Passed by stack address for both value types and reference types  Initialization can't be done by the called method – access is for read and write 59

public class Student { public string name; public string name; static void IncorrectModifyStudent(Student student) static void IncorrectModifyStudent(Student student) { student = new Student("Changed: " + student.name); student = new Student("Changed: " + student.name); } static void ModifyStudent(ref Student student) static void ModifyStudent(ref Student student) { student = new Student("Changed: " + student.name); student = new Student("Changed: " + student.name); } static void Main() static void Main() { Student s = new Student("Nakov"); Student s = new Student("Nakov"); Console.WriteLine(s.name); // Nakov Console.WriteLine(s.name); // Nakov IncorrectModifyStudent(s); IncorrectModifyStudent(s); Console.WriteLine(s.name); // Nakov Console.WriteLine(s.name); // Nakov ModifyStudent(ref s); ModifyStudent(ref s); Console.WriteLine(s.name); // Changed: Nakov Console.WriteLine(s.name); // Changed: Nakov }} 60

Live Demo

class TestOutParameters { static void Main() static void Main() { Rectangle rect = new Rectangle(5, 10, 12, 8); Rectangle rect = new Rectangle(5, 10, 12, 8); Point location; Point location; Dimensions dimensions; Dimensions dimensions; // Location and dimension are not pre-initialized! // Location and dimension are not pre-initialized! rect.GetLocationAndDimensions( rect.GetLocationAndDimensions( out location, out dimensions); out location, out dimensions); Console.WriteLine("({0}, {1}, {2}, {3})", Console.WriteLine("({0}, {1}, {2}, {3})", location.x, location.y, location.x, location.y, dimensions.width, dimensions.height); dimensions.width, dimensions.height); // Result: (5, 10, 12, 8) // Result: (5, 10, 12, 8) }} 62

Live Demo

форум програмиране, форум уеб дизайн курсове и уроци по програмиране, уеб дизайн – безплатно програмиране за деца – безплатни курсове и уроци безплатен SEO курс - оптимизация за търсачки уроци по уеб дизайн, HTML, CSS, JavaScript, Photoshop уроци по програмиране и уеб дизайн за ученици ASP.NET MVC курс – HTML, SQL, C#,.NET, ASP.NET MVC безплатен курс "Разработка на софтуер в cloud среда" BG Coder - онлайн състезателна система - online judge курсове и уроци по програмиране, книги – безплатно от Наков безплатен курс "Качествен програмен код" алго академия – състезателно програмиране, състезания ASP.NET курс - уеб програмиране, бази данни, C#,.NET, ASP.NET курсове и уроци по програмиране – Телерик академия курс мобилни приложения с iPhone, Android, WP7, PhoneGap free C# book, безплатна книга C#, книга Java, книга C# Николай Костов - блог за програмиране Common Type SystemCommon Type System

1. Define a class Student, which contains data about a student – first, middle and last name, SSN, permanent address, mobile phone , course, specialty, university, faculty. Use an enumeration for the specialties, universities and faculties. Override the standard methods, inherited by System.Object : Equals(), ToString(), GetHashCode() and operators == and !=. 2. Add implementations of the ICloneable interface. The Clone() method should deeply copy all object's fields into a new object of type Student. 65

3. Implement the IComparable interface to compare students by names (as first criteria, in lexicographic order) and by social security number (as second criteria, in increasing order). 4. Create a class Person with two fields – name and age. Age can be left unspecified (may contain null value. Override ToString() to display the information of a person and if age is not specified – to say so. Write a program to test this functionality. 5. Define a class BitArray64 to hold 64 bit values inside an ulong value. Implement IEnumerable and Equals(…), GetHashCode(), [], == and !=. 66

6. * D efine the data structure binary search tree with operations for "adding new element", "searching element" and "deleting elements". It is not necessary to keep the tree balanced. Implement the standard methods from System.Object – ToString (), Equals(…), GetHashCode() and the operators for comparison == and !=. Add and implement the ICloneable interface for deep copy of the tree. Remark: Use two types – structure BinarySearchTree (for the tree) and class TreeNode (for the tree elements). Implement IEnumerable to traverse the tree. 6. * Define the data structure binary search tree with operations for "adding new element", "searching element" and "deleting elements". It is not necessary to keep the tree balanced. Implement the standard methods from System.Object – ToString (), Equals(…), GetHashCode() and the operators for comparison == and !=. Add and implement the ICloneable interface for deep copy of the tree. Remark: Use two types – structure BinarySearchTree (for the tree) and class TreeNode (for the tree elements). Implement IEnumerable to traverse the tree. 67