UNIVERSITY of SOUTH ASIA 1Md Rezaul Huda Reza 1 Application and Web Development Errors. Debugging....

download UNIVERSITY of SOUTH ASIA 1Md Rezaul Huda Reza 1 Application and Web Development Errors. Debugging. Testing.

If you can't read please download the document

description

UNIVERSITY of SOUTH ASIA 3Md Rezaul Huda Reza UNIVERSITY of SOUTH ASIA 3 Compilation Errors The compiler converts source code into MSIL (MicroSoft Intermediate Language) which can be executed by the CLR (Common Language Runtime). In Visual Studio, we run the compiler by Building the application The compiler works by applying language rules It checks errors in syntax (grammar) It checks resources are present (so it will pick up a missing needed using statement) It checks that types match Compilation of program source code is a totally separate process from running a program. We sort out the compilation errors before we can run a program.

Transcript of UNIVERSITY of SOUTH ASIA 1Md Rezaul Huda Reza 1 Application and Web Development Errors. Debugging....

UNIVERSITY of SOUTH ASIA 1Md Rezaul Huda Reza 1 Application and Web Development Errors. Debugging. Testing. UNIVERSITY of SOUTH ASIA 2Md Rezaul Huda Reza UNIVERSITY of SOUTH ASIA 2 Errors Design errors the program simply doesnt do what was intended Example: a program is supposed to square each value of a list, but in fact it doubles each value Runtime errors are unplanned they give rise to premature abortion of a program run. A runtime error often can be handled in a program Compilation errors - before run-time UNIVERSITY of SOUTH ASIA 3Md Rezaul Huda Reza UNIVERSITY of SOUTH ASIA 3 Compilation Errors The compiler converts source code into MSIL (MicroSoft Intermediate Language) which can be executed by the CLR (Common Language Runtime). In Visual Studio, we run the compiler by Building the application The compiler works by applying language rules It checks errors in syntax (grammar) It checks resources are present (so it will pick up a missing needed using statement) It checks that types match Compilation of program source code is a totally separate process from running a program. We sort out the compilation errors before we can run a program. UNIVERSITY of SOUTH ASIA 4Md Rezaul Huda Reza UNIVERSITY of SOUTH ASIA 4 Errors at Runtime Code is compiled runtime errors trigger (raise) the creation of an exception object some circumstances are beyond programmers control You have assumed nothing unusual would occur Unless provisions are made for handling exceptions, your program may crash or produce erroneous results UNIVERSITY of SOUTH ASIA 5Md Rezaul Huda Reza UNIVERSITY of SOUTH ASIA Exceptional behaviours An exception is an unusual situation that could occur in your program. As a programmer, you should anticipate any abnormal behaviour that could be caused by the user entering wrong information that could otherwise lead to unpredictable results. Exception handling is he ability to deal with a programs eventual abnormal behaviour 5 UNIVERSITY of SOUTH ASIA 6Md Rezaul Huda Reza UNIVERSITY of SOUTH ASIA 6 Exception-Handling Techniques Use if statements if you can can be used to guard against common problems such as integer divide by zero Use try{ } catch{ } for serious errors that occur infrequently UNIVERSITY of SOUTH ASIA 7Md Rezaul Huda Reza UNIVERSITY of SOUTH ASIA 7 trycatchfinally Blocks try { // Statements } catch [(ExceptionClassName exceptionIdentifier)] { // Exception handler statements } // [additional catch clauses] [ finally { // Statements }] Notice square brackets indicate optional entry finally clause is optional UNIVERSITY of SOUTH ASIA 8Md Rezaul Huda Reza UNIVERSITY of SOUTH ASIA Exceptions in the.NET Framework /1 To support exception handling, the.NET Framework provides a special class called Exception. Once the compiler encounters an error, the Exception class allows you to identify the type of error and take an appropriate action. Exception mostly serves as the general class of exceptions. Microsoft derived various classes from Exception to handle different types of errors 8 UNIVERSITY of SOUTH ASIA 9Md Rezaul Huda Reza UNIVERSITY of SOUTH ASIA Exceptions in the.NET Framework /2 use catch as if it were a method. By default, an exception is first of type Exception. try { // Process the normal flow of the program here } catch(Exception e) { // Deal with the exception here } 9 UNIVERSITY of SOUTH ASIA 10Md Rezaul Huda Reza UNIVERSITY of SOUTH ASIA Exception class If you declare the exception as an Exception type, this class will identify the error. One of the properties of the Exception class is called Message. use Exception.Message property to display an error message if you want. 10 UNIVERSITY of SOUTH ASIA 11Md Rezaul Huda Reza UNIVERSITY of SOUTH ASIA 11 Example on Examining Exception Object try { int y = 0; // throw Exception int x = 1 / y; } catch (Exception e) // you can ommit the argument in this case { MessageBox.Show (e.Message); } The Message property of the instance of class Exception UNIVERSITY of SOUTH ASIA 12Md Rezaul Huda Reza UNIVERSITY of SOUTH ASIA 12 Types of Exception Classes Example: catch (Exception e) {.. Not considered good programming practice It is best to examine the type of Exception thrown and deal with it appropriately 2 major types SystemException built-in to C#.NET ApplicationException Derive from this class when you write your own exception class (custom exceptions) UNIVERSITY of SOUTH ASIA 13Md Rezaul Huda Reza UNIVERSITY of SOUTH ASIA 13 SystemException Classes ( Over 70 classes derive from the System.Exception class ) UNIVERSITY of SOUTH ASIA 14Md Rezaul Huda Reza UNIVERSITY of SOUTH ASIA 14 Example: System.DivideByZeroException Derived class of System.ArithmeticException class Thrown when an attempt to divide by zero occur for integer data types.... catch (System.DivideByZeroException de) { MessageBox.Show(de.Message); } UNIVERSITY of SOUTH ASIA 15Md Rezaul Huda Reza UNIVERSITY of SOUTH ASIA 15 Filtering Multiple Exceptions You can include multiple catch clauses Should be placed from most specific to the most generic If a generic catch is included, it should always be placed last UNIVERSITY of SOUTH ASIA 16Md Rezaul Huda Reza UNIVERSITY of SOUTH ASIA 16 Example on Filtering Multiple Exceptions try { int n = int.Parse(TextBox1.Text); int y = int.Parse(TextBox1.Text); int z = y / n; if (z==10) { Object o = new Object(); o = null; o.ToString(); } catch (DivideByZeroException e1) { Label1.Text = " Error 1: " + e1.Message; } catch (FormatException e2) { Label1.Text = " Error 2: " + e2.Message; } catch (Exception ex) { Label1.Text = " General Error : " + ex.Message; } UNIVERSITY of SOUTH ASIA 17Md Rezaul Huda Reza Throwing exceptions In C#, it is possible to throw an exception programmatically. The 'throw' keyword is used for this purpose. throw exception_obj; 17 UNIVERSITY of SOUTH ASIA 18Md Rezaul Huda Reza Throw example Public static string monthName (int month) { switch (month) { case 1 : return: January; case 2 : return: February; case 3: .. case 12: return December; default : throw new ArgumentOutOfRangeException(Bad month); } 18 If the integer is out of range the method does not return anything UNIVERSITY of SOUTH ASIA 19Md Rezaul Huda Reza UNIVERSITY of SOUTH ASIA 19 Debugging Purpose: to correct those logic errors that keep your application from running correctly Visual studio: integrated debugging functions. stop at procedure locations, inspect memory and register values, change variables, observe message traffic, and get a close look at what your code does. UNIVERSITY of SOUTH ASIA 20Md Rezaul Huda Reza UNIVERSITY of SOUTH ASIA 20 The Debugger The Debugger is not meant to handle runtime Exceptions it is meant to help you determine their source Possible to insert breakpoints, so that program will stop at them and then variables etc can be examined to determine the cause of the problem UNIVERSITY of SOUTH ASIA 21Md Rezaul Huda Reza UNIVERSITY of SOUTH ASIA 21 Getting Started 1 The Start and Step Into commands will both launch your application and begin a debugging session. 2 Attach to Process: break into a running application and begin a debug session popular for web application developers who want to debug an already running instance of a web application or web service 3 Just-In-Time debugging to step in during an application crash Visual Studio can take you directly to the line of code responsible for the unhandled exception UNIVERSITY of SOUTH ASIA 22Md Rezaul Huda Reza UNIVERSITY of SOUTH ASIA 22 Debug Symbols vital for a successful debugging session Breakpoints Stepping Through Code Viewing State help the debugger correlate instructions in your application back to file names and line numbers in your source code stored in a program database file with a.pdb extension UNIVERSITY of SOUTH ASIA 23Md Rezaul Huda Reza UNIVERSITY of SOUTH ASIA 23 Breakpoints tell the debugger where and when we want to pause the execution of our application. When the debugger is in break mode, you can examine objects and local variables to see what is going on red dot will appear in the left margin of the editor Right click on an existing breakpoint to set properties, disable, or delete the breakpoint. When execution reaches a breakpoint, the debugger pauses all of the applications threads and allows you to inspect the state of your application UNIVERSITY of SOUTH ASIA 24Md Rezaul Huda Reza 24 Stepping Through Code Once you pause execution you have the ability to step through code, in other words, execute code one line at a time. 3 methods: Step Into Step Over Step Out UNIVERSITY of SOUTH ASIA 25Md Rezaul Huda Reza 25 Step Into/ Step Over the Step Into command will enter the method and break again on the first line of code inside the method Step Over command will execute the entire method call and break on the next line of code in the current method. Use Step Into if you want to see what happens inside a method call; use Step Over if you only want to execute the entire method and continue in the current code block. UNIVERSITY of SOUTH ASIA 26Md Rezaul Huda Reza UNIVERSITY of SOUTH ASIA 26 Step Out can use when you want to execute the rest of the current method and return to the calling method. Step Out will break execution at the return point in the calling function. UNIVERSITY of SOUTH ASIA 27Md Rezaul Huda Reza UNIVERSITY of SOUTH ASIA 27 Viewing State view the data inside a variable is to place the mouse cursor over the variable in code and allow Visual Studio to display a Data Tip. DataTips are only available when the program is in break mode. If the object you are inspecting is a complex object, structure, or array, there will be a plus sign (+) to the left of the tip. If you hover over the + you can expand the DataTip to view additional fields and properties of the object in a tree like view. UNIVERSITY of SOUTH ASIA 28Md Rezaul Huda Reza 28 If you hover over the + you can expand the DataTip to view additional fields and properties of the object in a tree like view. you can continue to expand the nodes of the tree and drill further and further into the object UNIVERSITY of SOUTH ASIA 29Md Rezaul Huda Reza UNIVERSITY of SOUTH ASIA 29 Testing Purpose to test that every part of a program works correctly according to the program specification and to engender confidence in the correctness of the program Objective to show the presence of errors in a program. A non-trivial program is unlikely to be 100% error free. Testing involves : the design of test data, execution of the program with the test data and evaluation of the results obtained. UNIVERSITY of SOUTH ASIA 30Md Rezaul Huda Reza UNIVERSITY of SOUTH ASIA 30 Testing Generally the rate of error detection is proportional to the number of errors still remaining in the software. Consequently the number of errors presents declines exponentially over time. No. of errors Time 0 Testing often continues until it becomes uneconomic. Hence often bugs remain in software. UNIVERSITY of SOUTH ASIA 31Md Rezaul Huda Reza UNIVERSITY of SOUTH ASIA 31 Unit vs System testing Small programs comprising a single class are usually tested all at once. Larger programs are tested class by class, called unit testing, and then brought together to test the whole, called integration or system testing. UNIVERSITY of SOUTH ASIA 32Md Rezaul Huda Reza UNIVERSITY of SOUTH ASIA 32 Testing in the small Unit Testing: Exercising the smallest individually executable code units. Objectives: Find faults in the units and assure correct functional behavior of units. Usually performed by programmers. Integration Testing: Exercising two or more units or components. Objectives: Detect interface errors and assure the functionality of combined units. Performed by programmers or testing group. UNIVERSITY of SOUTH ASIA 33Md Rezaul Huda Reza UNIVERSITY of SOUTH ASIA 33 Testing in the large System Testing: Exercising the functionality, performance, reliability, and security of the entire system. Objectives: Find errors in the overall system behavior. Establish confidence in system functionality. Validate non-functional system requirements. Usually performed by a separate test group. UNIVERSITY of SOUTH ASIA 34Md Rezaul Huda Reza UNIVERSITY of SOUTH ASIA 34 Techniques Black box (functional): focuses on the range inputs and outputs of the program ignoring the actual construction of the code. White box (structural): tests each and every possible path through software according to the statements and logic of the code. Reviews or walkthroughs: desk checking, dry run Stepping through code with debugger UNIVERSITY of SOUTH ASIA 35Md Rezaul Huda Reza UNIVERSITY of SOUTH ASIA 35 Black box testing refers to the technique of testing a system with no knowledge of the internals of the system. Black Box testers do not have access to the source code, and are oblivious of the system architecture. attempts to find the following types of error incorrect or missing functions interface errors errors in data structures performance errors initialization and termination errors UNIVERSITY of SOUTH ASIA 36Md Rezaul Huda Reza UNIVERSITY of SOUTH ASIA 36 Example Suppose a program must accept the price of an orange, the number of oranges requested and to generate the total cost. The price of an orange will be less than 1.00 The number of oranges will be in the range 1 to 20 inclusive. A suitable error message should be displayed if either input entry in invalid. UNIVERSITY of SOUTH ASIA 37Md Rezaul Huda Reza UNIVERSITY of SOUTH ASIA 37 Test planning 1.Identify the inputs and outputs Number oranges Cost Price Error Message 2.Decide on all possible ranges of the inputs and outputs The type and limits of the values input and output (as per specification or assumed) are: Number : Minimum integer Maximum integer 120 Price: Minimum float Maximum float Cost : Minimum Maximum Error : message - number error, price error UNIVERSITY of SOUTH ASIA 38Md Rezaul Huda Reza UNIVERSITY of SOUTH ASIA 38 Example of test plan The test plan must cover wide range of cases: UNIVERSITY of SOUTH ASIA 39Md Rezaul Huda Reza UNIVERSITY of SOUTH ASIA 39 White Box Testing technique of testing a system with knowledge of the internals of the system. White Box testers have access to the source code and are aware of the system architecture. UNIVERSITY of SOUTH ASIA 40Md Rezaul Huda Reza UNIVERSITY of SOUTH ASIA Unit Testing The first unit testing software was called SUnit Developed by Kent Beck (from Extreme Programming fame) and Erich Gamma (one of the Gang of Four, from Design Patterns fame) Used for testing SmallTalk code Test frameworks now exist for many programming languages JUnit for Java, CppUnit for C++, NUnit for.NET, many others Known collectively as xUnit UNIVERSITY of SOUTH ASIA 41Md Rezaul Huda Reza UNIVERSITY of SOUTH ASIA NUnit In Visual Studio 2005 required NUnit to be installed separately Unit testing was only built into the Team editions But, lucky you Since Visual Studio 2008, VS supports unit testing out of the box even for the Professional edition UNIVERSITY of SOUTH ASIA 42Md Rezaul Huda Reza UNIVERSITY of SOUTH ASIA Unit Testing in VS Works with all languages supported by the.NET framework The test can be written in a different language than the code it is testing (e.g. code in C# and test in VB.NET) The testing tools dont offer features for testing UIs (e.g. automatically entering text or clicking buttons) So, very important to put all your application logic in testable classes thin UI layer Remember separation of concerns UNIVERSITY of SOUTH ASIA 43Md Rezaul Huda Reza UNIVERSITY of SOUTH ASIA Test Advice What should I test? Every non trivial algorithm Anything that has ever broken Test should be Quick If they take too long you wont run them so often Self contained - If there is an error in one test it shouldnt propagate to others KISS (Keep It Short and Simple) UNIVERSITY of SOUTH ASIA 44Md Rezaul Huda Reza UNIVERSITY of SOUTH ASIA Tests as Separate Projects Visual Studio 2010 will automatically create a new project for tests NOTE: Visibility restrictions apply, so if you want to test a class from a different namespace then it needs to have public visibility The same applies to methods UNIVERSITY of SOUTH ASIA 45Md Rezaul Huda Reza UNIVERSITY of SOUTH ASIA Testing the Calculator Create unit tests to test the calculator application Available on teachmat A Calculator class contains the methods to carry out the calculations No logic remains in the UI layer UNIVERSITY of SOUTH ASIA 46Md Rezaul Huda Reza UNIVERSITY of SOUTH ASIA Calculator Class class Calculator : ICalculator { public decimal add(decimal a, decimal b) { return a + b; } public decimal subtract(decimal a, decimal b) { return a - b; } public decimal multiply(decimal a, decimal b) { return a * b; } public decimal divide(decimal a, decimal b) { //Should really check for a divide by zero return a / b; } UNIVERSITY of SOUTH ASIA 47Md Rezaul Huda Reza UNIVERSITY of SOUTH ASIA Creating Unit Tests In Visual Studio 2010, right-click on a class and select Create Unit Tests Select the methods for which you want to create tests Create a new project for tests or select an existing one UNIVERSITY of SOUTH ASIA 48Md Rezaul Huda Reza UNIVERSITY of SOUTH ASIA Test Class Visual Studio 2010 automatically creates test classes and skeleton code More than just skeleton, actually [TestMethod()] public void multiplyTest() { Calculator target = new Calculator(); // TODO: Initialize to an appropriate value Decimal a = new Decimal(); // TODO: Initialize to an appropriate value Decimal b = new Decimal(); // TODO: Initialize to an appropriate value Decimal expected = new Decimal(); // TODO: Initialize to an appropriate value Decimal actual; actual = target.multiply(a, b); Assert.AreEqual(expected, actual); Assert.Inconclusive("Verify the correctness of this test method."); } The test method created for the testing the multiply method UNIVERSITY of SOUTH ASIA 49Md Rezaul Huda Reza UNIVERSITY of SOUTH ASIA Attributes Visual Studio 2010 uses attributes to annotate test elements [TestClass()] specifies a class containing unit tests [TestMethod()] defines a test [TestInitialize()] runs before each test in the class [TestCleanup()] runs after each test in the class [ExpectedException()] allows testing for exceptions [Ignore()] makes it possible to ignore a test UNIVERSITY of SOUTH ASIA 50Md Rezaul Huda Reza UNIVERSITY of SOUTH ASIA Assertions Assertions are used to test whether an actual post- condition is the same as an expected post-condition VS contains many static methods for assertion in the Assert class All static methods in the Assert class will evaluate either to true (the test has passed) or false (not passed), with the exception of Fail which will always fail If more than one assertion exist within one test, the test will stop as soon as the first assertion fails UNIVERSITY of SOUTH ASIA 51Md Rezaul Huda Reza UNIVERSITY of SOUTH ASIA Assertions Some static methods: AreEqual true if both arguments have same value (makes call to Equals method for non- primitive data types) AreSame true if two references point to the same object IsTrue true if it is passed something that evaluates to true IsInstanceOfType - true if it is passed something that is of a specified type IsNull true if what it is passed in is null UNIVERSITY of SOUTH ASIA 52Md Rezaul Huda Reza UNIVERSITY of SOUTH ASIA Testing Add() [TestMethod()] public void addTest() { Decimal a = 2.5m; Decimal b = m; Decimal expected = a + b; Decimal actual; actual = target.add(a, b); Assert.AreEqual(expected, actual); Assert.IsInstanceOfType(a, typeof(Decimal)); } This is what we expect This is what add() returns Do the results match? When an assertion fails it throws an AssertFailedException, which is picked up by the unit test engine UNIVERSITY of SOUTH ASIA 53Md Rezaul Huda Reza UNIVERSITY of SOUTH ASIA Running Tests in VS All unit testing-related things are under Test menu Which have passed or failed states why they failed UNIVERSITY of SOUTH ASIA 54Md Rezaul Huda Reza UNIVERSITY of SOUTH ASIA Ignoring Tests Sometimes it may be useful to ignore tests E.g. if test functionality not implemented yet Use Ignore attribute [TestMethod()] [Ignore()] public void multiplyTest(){} Is now greyed-out Test will be ignored UNIVERSITY of SOUTH ASIA 55Md Rezaul Huda Reza UNIVERSITY of SOUTH ASIA Testing Exception What if we want to test exception handling? It is possible to write tests that only pass if an exception of the expected type is thrown [TestMethod()] [ExpectedException(typeof(DivideByZeroException))] public void divideByZeroTest() { Decimal result = target.divide(10, 0); } Tests for an exception UNIVERSITY of SOUTH ASIA 56Md Rezaul Huda Reza Reviewing programming concepts (plus new ones) 56 UNIVERSITY of SOUTH ASIA 57Md Rezaul Huda Reza UNIVERSITY of SOUTH ASIA Md Rezaul Huda Reza 57 UNIVERSITY of SOUTH ASIA 58Md Rezaul Huda Reza UNIVERSITY of SOUTH ASIA Enumerations in C# Syntax: enum { const1, const2,} a distinct type consisting of a set of named constants By default, the first enumerator has the value 0, and the value of each successive enumerator is increased by 1. The underlying type can be any integral type except char 58 UNIVERSITY of SOUTH ASIA 59Md Rezaul Huda Reza UNIVERSITY of SOUTH ASIA Enumerations in C Examples Creating an enum: enum CalculationTypes { Add, Subtract, Multiply, Divide } Declaring a variable of type enum: CalculationTypes ct = CalculationTypes.Subtract; 59 UNIVERSITY of SOUTH ASIA 60Md Rezaul Huda Reza UNIVERSITY of SOUTH ASIA Converting Enumerations in C converting from enum type to an integral type (an explicit cast is needed) int x = (int) CalculationTypes.Multiply; CalculationTypes c = (CalculationTypes)x; we can retrieve the literal as a string from the numeric constant string s = CalculationTypes.Multiply.ToString(); 60 UNIVERSITY of SOUTH ASIA 61Md Rezaul Huda Reza UNIVERSITY of SOUTH ASIA Interface -recap Md Rezaul Huda Reza 61 namespace CalculatorApplication { interface ICalculator { decimal add(decimal a, decimal b); decimal subtract(decimal a, decimal b); decimal multiply(decimal a, decimal b); decimal divide(decimal a, decimal b); } UNIVERSITY of SOUTH ASIA 62Md Rezaul Huda Reza UNIVERSITY of SOUTH ASIA Class implementing an interface Md Rezaul Huda Reza 62 class Calculator : ICalculator { public decimal add(decimal a, decimal b) { return a + b; } public decimal subtract(decimal a, decimal b) { return a - b; } public decimal multiply(decimal a, decimal b) { return a * b; } public decimal divide(decimal a, decimal b) { //Should really check for a divide by zero return a / b; } UNIVERSITY of SOUTH ASIA 63Md Rezaul Huda Reza UNIVERSITY of SOUTH ASIA Class 2 implementing an interface Md Rezaul Huda Reza 63 class Calculator : ICalculator { public decimal add(decimal a, decimal b) { return Math.Round(a + b, 2); } public decimal subtract(decimal a, decimal b) { return Math.Round(a - b, 2); } public decimal multiply(decimal a, decimal b) { return Math.Round(a * b, 2); } public decimal divide(decimal a, decimal b) { //Should really check for a divide by zero return Math.Round(a / b, 2); } UNIVERSITY of SOUTH ASIA 64Md Rezaul Huda Reza UNIVERSITY of SOUTH ASIA Main Form -1: enumeration as parameter Notice the try and catch any better use of it that you can think of? Notice syb-typing (polymorphism). The calculator is instantiated to different objects in the if statement Md Rezaul Huda Reza 64 public partial class Form1 : Form { public Form1() { InitializeComponent(); private void Calculate(CalculationTypes type) { decimal n1, n2, result; ICalculator calculator; try { n1 = Decimal.Parse(textBox1.Text); n2 = Decimal.Parse(textBox2.Text); } catch (Exception) { lblResult.Text = "Must input only numbers"; return; } if (cbRound.Checked) { calculator = new RoundedCalculator(); } else { calculator = new Calculator(); } UNIVERSITY of SOUTH ASIA 65Md Rezaul Huda Reza UNIVERSITY of SOUTH ASIA Main Form-2 : using the enumeration CalculationTypes Md Rezaul Huda Reza switch (type) { case CalculationTypes.Add: result = calculator.add(n1, n2); break; case CalculationTypes.Subtract: result = calculator.subtract(n1, n2); break; case CalculationTypes.Multiply: result = calculator.multiply(n1, n2); break; case CalculationTypes.Divide: result = calculator.divide(n1, n2); break; default: result = 0; break; } lblResult.Text = "Result: " + result; } UNIVERSITY of SOUTH ASIA 66Md Rezaul Huda Reza UNIVERSITY of SOUTH ASIA Main Form -3 Md Rezaul Huda Reza private void btnAdd_Click(object sender, EventArgs e) { Calculate(CalculationTypes.Add); } private void btnSubtract_Click(object sender, EventArgs e) { Calculate(CalculationTypes.Subtract); } private void btnMultiply_Click(object sender, EventArgs e) { Calculate(CalculationTypes.Multiply); } private void btnDivide_Click(object sender, EventArgs e) { Calculate(CalculationTypes.Divide); }