I am using enums in C# to calculate the areas of different shapes. Below is my code:
using System;
class Area
{
public enum Shape{Circle,Square};
public void AreaShape(int x,Shape ob1)
{
double a;
switch(x)
{
case (int)Shape.Circle:
a=Math.PI*x*x;
Console.WriteLine("Circle "+a);
break;
case (int)Shape.Square:
a=x*x;
Console.WriteLine("Square "+a);
break;
default:
Console.WriteLine("Invalid");
break;
}
}
}
class MyTestOne
{
public static void Main(String[] a)
{
Area obj1=new Area();
obj1.AreaShape(15,Area.Shape.Circle);
obj1.AreaShape(15,Area.Shape.Square);
}
}
The following produces an error:
obj1.AreaShape(15,Shape.Circle);
obj1.AreaShape(15,Shape.Square);
How can I get the following output?
Circle 225*pi
Square 225
When I use Area.Shape.Circle and Area.Shape.Square, the output is:
Invalid
Invalid
Pass Shape enum class not int x variable
switch (ob1)
{
case Shape.Circle:
a = Math.PI * x * x;
Console.WriteLine("Circle " + a);
break;
case Shape.Square:
a = x * x;
Console.WriteLine("Square " + a);
break;
default:
Console.WriteLine("Invalid");
break;
}
Your switch statement switches on x, which you're always passing in as 15. You should be switching on the ob1 enumeration variable and you won't need the cast.
Related
I am beginner to C# and am trying to get my second class, MyCalc2, to inherit from MyCalc. But I encounter the following error message in regards to MyCalc2:
There is no argument given that corresponds to the required formal parameter 'x' of 'MyCalc.MyCalc(int, int, string, string)'
The goal here is to just add another class that inherits from the base class.
I know that I need to add something like 'MyCalc: base(x)' to my base class but am lost to where to place the parameter (if that is even the correct thing to do). Any guidance would be appreciated. Here is what I have so far:
using System;
class MyCalc
{
// class variable
public int x;
public int z;
public string y;
public string n;
// constructor
public MyCalc(int x, int z, string y, string n)
{
this.x = x; // assign the parameter passed to the class variable
this.z = z;
this.y = y;
this.n = n;
}
// calculate the operations
public int GetAdd()
{
return (this.x + this.z);
}
public int GetSubtract()
{
return (this.x - this.z);
}
public int GetMultiply()
{
return (this.x * this.z);
}
public int GetDivide()
{
return (this.x / this.z);
}
public string GetYes()
{
return (this.y);
}
public string GetNo()
{
return (this.n);
}
}
class MyCalc2:MyCalc //where the error is occurring
{
static void Main(string[] args)
{
bool repeat = false;
do
{
repeat = false;
int x = 0; int z = 0; string y; string n;
Console.WriteLine("Enter the First Number");
x = Convert.ToInt32(Console.ReadLine());
Console.WriteLine("Enter the Second Number");
z = Convert.ToInt32(Console.ReadLine());
//Using a switch statement to perform calculation:
Console.WriteLine("Enter operator\r");
switch (Console.ReadLine())
{
case "+":
Console.WriteLine($"The Answer is: {x} + {z} = " + (x + z));
break;
case "-":
Console.WriteLine($"The Answer is: {x} - {z} = " + (x - z));
break;
case "*":
Console.WriteLine($"The Answer is: {x} + {z} = " + (x + z));
break;
case "/":
Console.WriteLine($"The Answer is: {x} - {z} = " + (x - z));
break;
}
//Repeat or Exit program using the do-while loop:
string input = Console.ReadLine();
Console.WriteLine("Do you want another operation(Y / N) ?");
input = Console.ReadLine();
repeat = (input.ToUpper() == "Y");
}
while (repeat);
Console.WriteLine("Thanks for using our system.");
Console.ReadKey();
}
}
MyCalc2 does not have a way of initializing MyCalc (Base Class) Because in your BaseClass you do not have a parameter less constructor.
Solution:
Add a param less constructor in Base Class
Add a constructor in Derived class which has a way of calling base class constructor
for your code below should work:
class MyCalc2 : MyCalc
{
public MyCalc2 () : base(0, 0, "", "")
{
}
}
MyCalc2 has no explicit constructor. Which means it has only one implicit constructor which takes no arguments and sets no values. If made explicitly it would look like this:
public MyCalc2()
{
}
However, MyCalc does have an explicit constructor. Which means it has no implicit constructor. And its constructor does take arguments:
public MyCalc(int x, int z, string y, string n)
{
this.x = x; // assign the parameter passed to the class variable
this.z = z;
this.y = y;
this.n = n;
}
So when you create an instance of MyCalc2 it has no way of providing any values to MyCalc. You essentially have three options:
Add a constructor to MyCalc (you can have as many constructors as you want, as long as the parameters differ) which takes no parameters. However, in that case the class-level values for MyCalc would all be default values. You'd have to set them explicitly after constructing the object.1
Add a constructor to MyCalc2 which accepts those values and passes them to the parent constructor, or at least passes default values to the parent constructor.
Don't use inheritance here.
Honestly, in this case I'd go with the third option. What is inheritance meant to accomplish here? MyCalc2 isn't meaningfully an instance of MyCalc. All it does it hold the initial entry point of the application (the Main method), and that's really all it should do.
The logic in your Main method should create and use an instance of MyCalc, but the class which has that Main method shouldn't try to be an instance of MyCalc. That will only cause more confusion than solve any meaningful problems.
1 Side Note: Public class fields are historically a bad habit to get into in object-oriented programming. There's a variety of talk on the subject, and you'll see this often as you continue in your experience. In general you want your objects to expose behaviors, not values. The methods on the object look somewhat Java-like in convention. For C# conventions consider using properties (which compile down to methods themselves, the syntax is just semantically different). You can have { get; set; } auto-properties for the values themselves, and explicit read-only { get { /*...*/ } } properties for the calculated values.
Here is a possible solution. There are two classes MyClass, for the calculator (you may want to rename it) and Propram. Program holds just the method Main, which get your program started. It works like this, but there are some bugs left. I leave it to you to fix them. Except that you miss a clear understanding of the concepts class and inheritance, your code is not too bad for a beginner. It is almost working.
using System;
namespace TestCalculator
{
class MyCalc
{
// class variable
public int x;
public int z;
public string y;
public string n;
// constructor
public MyCalc(int x, int z, string y, string n)
{
this.x = x; // assign the parameter passed to the class variable
this.z = z;
this.y = y;
this.n = n;
}
// calculate the operations
public int GetAdd()
{
return (this.x + this.z);
}
public int GetSubtract()
{
return (this.x - this.z);
}
public int GetMultiply()
{
return (this.x * this.z);
}
public int GetDivide()
{
return (this.x / this.z);
}
public string GetYes()
{
return (this.y);
}
public string GetNo()
{
return (this.n);
}
}
class Program
{
static void Main(string[] args)
{
bool repeat = false;
do
{
repeat = false;
int x = 0; int z = 0; string y; string n;
Console.WriteLine("Enter the First Number");
x = Convert.ToInt32(Console.ReadLine());
Console.WriteLine("Enter the Second Number");
z = Convert.ToInt32(Console.ReadLine());
//Using a switch statement to perform calculation:
Console.WriteLine("Enter operator\r");
switch (Console.ReadLine())
{
case "+":
Console.WriteLine($"The Answer is: {x} + {z} = " + (x + z));
break;
case "-":
Console.WriteLine($"The Answer is: {x} - {z} = " + (x - z));
break;
case "*":
Console.WriteLine($"The Answer is: {x} + {z} = " + (x + z));
break;
case "/":
Console.WriteLine($"The Answer is: {x} - {z} = " + (x - z));
break;
}
//Repeat or Exit program using the do-while loop:
string input = Console.ReadLine();
Console.WriteLine("Do you want another operation(Y / N) ?");
input = Console.ReadLine();
repeat = (input.ToUpper() == "Y");
}
while (repeat);
Console.WriteLine("Thanks for using our system.");
Console.ReadKey();
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ArithmaticOperation
{
class Program
{
delegate double ArithmaticDelegate(double x, double y);
static void Menu()
{
Console.WriteLine("Select an arithmatic operation");
Console.WriteLine("1)Addition");
Console.WriteLine("2)Subtraction");
Console.WriteLine("3)Multiplication");
Console.WriteLine("4)Division");
Console.WriteLine("5)Remainder");
Console.WriteLine("6)Quit");
}
static double Add(double a, double b)
{
return a + b;
}
static double Subtract(double a, double b)
{
return a - b;
}
static double Multiply(double a, double b)
{
return a * b;
}
static double Divide(double a, double b)
{
return a / b;
}
static double Modulus(double a, double b)
{
return a % b;
}
static void Main(string[] args)
{
int operation;
ArithmaticDelegate arithmatic;
double x, y;
do
{
Console.WriteLine("Enter two numbers seperated by Enter");
x = double.Parse(Console.ReadLine());
y = double.Parse(Console.ReadLine());
Console.Clear();
Menu();
operation = int.Parse(Console.ReadLine());
switch (operation)
{
//Addition
case 1:
arithmatic = new ArithmaticDelegate(Add);
break;
//Subtraction
case 2:
arithmatic = new ArithmaticDelegate(Subtract);
break;
//Multiplication
case 3:
arithmatic = new ArithmaticDelegate(Multiply);
break;
//Division
case 4:
arithmatic = new ArithmaticDelegate(Divide);
break;
//Remainder
case 5:
arithmatic = new ArithmaticDelegate(Modulus);
break;
default:
Console.WriteLine("Exiting program");
break;
}
Console.Clear();
Console.WriteLine(arithmatic(x, y));
Console.WriteLine("Press any key to continue");
Console.ReadKey(true);
Console.Clear();
} while (operation != 6);
}
}
}
I am trying to write a simple calculator using delegates. The code below would give an error at the line 81 "Console.WriteLine(arithmatic(x,y));" reporting that the variable arithmatic is unassigned local variable. I believe the cause has something to do with the variable scope in the do-while and the switch body, however the variable is declared outside the do-while so its scope should span the entire main method, and anything assigned to it from within the do-while and switch statement should remain in effect after its outside. Yet the compiler still report its uninitialized/unassigned
You are getting error message because arithmatic is not initialized in all the cases of switch statement (meaning not assigned in all execution paths).
To fix this issue:
either have some dummy method and assign that dummy method in default
static double DummyMethod(double a, double b)
{
return 6; // or any number other than 1 through 5
}
and in default case, arithmatic = DummyMethod;
(or) initialze as below:
So, to fix the error: please modify your programs to initialize arithematic as below:
ArithmaticDelegate arithmatic = null;
and then surround your arithematic call with if as below:
if (arithmatic != null)
{
Console.WriteLine(arithmatic(x, y));
}
or return in default case to skip the execution path when control enters into default case.
I want to write on screen result i get after completing actions at the bottom of the code. But i don't want to use Console.WriteLine() in "IF" function i want to call it as delegate carying value but it says unasigned. (site says mostly code but i dont have to say anything else so i just type something here :D )
namespace ConsoleApp5
{
class program
{
delegate int first(int a, int b);
static void Main()
{
first beta;
int result;
Console.Write("insert number A: ");
int.TryParse(Console.ReadLine(), out int a);
if (a == 0)
{
Console.WriteLine("not a number");
Environment.Exit(0);
}
Console.Write("insert number B: ");
int b = int.Parse(Console.ReadLine());
if (a == 0)
{
Console.WriteLine("not a number");
Environment.Exit(0);
}
Console.WriteLine("plus(1) or minus (0)");
int c = int.Parse(Console.ReadLine());
if (c == 1)
{
beta = plus;
result = beta(a, b);
Console.WriteLine(result);
}
else if (c == 0)
{
beta = minus;
result = beta(a, b);
Console.WriteLine(result);
}
beta(); // PROBLEM HERE, I WANT TO WRITE ANSWER FROM THIS
//instead of "Console.WriteLine(result);" inside function
}
private static int plus(int a, int b)
{
return a + b;
}
private static int minus(int a, int b)
{
return a - b;
}
}
}
Example what i mean i want to accomplish but a bit in different way.
using System;
namespace consoleApplication4
{
class Program{
Delegate void Message();
static void Main (string[] args)
{
Message mes;
if (DateTime.Now.Hour < 12)
{
mes=GoodMorning;
}
else{
mes=GoodEvening;
}
mes(); //this does what i want here but in code above something is missing
Console.ReadKey();
}
private static void GoodMorning(){
console.WriteLine("Good Morning");
}
Private static void GoodEvening(){
Console.WriteLine("Good Evening");
}}}
You already have correct code to call your delegate in both branches of if. So to get code almost working those two lines calling beta need to be moved out of both branches:
if (c == 1)
{
beta = plus;
}
else if (c == 0)
{
beta = minus;
}
result = beta(a, b);
Console.WriteLine(result);
Now the other problem is still there - your if checks have 3 outcomes (0, 1, other) but beta is only assigned in two of cases. So we need to add that "other" case too with some desired output (or simply failure), switch statement expresses it better than chained ifs:
switch (c)
{
case 1: beta = plus; break;
case 0: beta = plus; break;
default: beta = (a,b)=>""; break;
// alternatively to fail: default: return 0;
}
result = beta(a, b);
Console.WriteLine(result);
I want to let the users input mathematics expression in terms of x and y as natural as possible. For example, instead of typing Complex.Sin(x), I prefer to use just Sin(x).
The following code fails when Sin(x), for example, is defined by the user.
using Microsoft.CodeAnalysis.CSharp.Scripting;
using System;
using System.Numerics;
using static System.Console;
using static System.Numerics.Complex;
namespace MathEvaluator
{
public class Globals
{
public Complex x;
public Complex y;
}
class Program
{
async static void JobAsync(Microsoft.CodeAnalysis.Scripting.Script<Complex> script)
{
Complex x = new Complex(1, 0);
Complex y = new Complex(0, 1);
try
{
var result = await script.RunAsync(new Globals { x = x, y = y });
WriteLine($"{x} * {y} = {result.ReturnValue}\n");
}
catch (Exception e)
{
WriteLine(e.Message);
}
}
static void Main(string[] args)
{
Console.Write("Define your expression in x and y: ");
string expression = Console.ReadLine(); //user input
var script = CSharpScript.Create<Complex>(expression, globalsType: typeof(Globals));
script.Compile();
JobAsync(script);
}
}
}
Question
How to use using static directive for dynamically generated code?
You can supply script options to the Create function that define the references and imports that should be set for your script:
var scriptOptions = ScriptOptions.Default
.WithReferences("System.Numerics")
.WithImports("System.Numerics.Complex");
var script = CSharpScript.Create<Complex>(expression, options: scriptOptions, globalsType: typeof(Globals));
That way, you can use Sin(x) in the input:
Define your expression in x and y: Sin(x)
(1, 0) * (0, 1) = (0,841470984807897, 0)
However, when dealing with user input, you should consider writing your own parser. This allows you on one hand to define your own “aliases” for functions (e.g. a lower case sin) or even a more lenient syntax; on the other hand, it also adds more security because right now, nothing prevents me from doing this:
Define your expression in x and y: System.Console.WriteLine("I hacked this calculator!")
I hacked this calculator!
(1, 0) * (0, 1) = (0, 0)
I created a quick (and dirty) parser using Roslyn’s syntax tree parsing. Obviously this is rather limited (e.g. since it requires all return values of subexpressions to be Complex), but this could give you an idea of how this could work:
void Main()
{
string input = "y + 3 * Sin(x)";
var options = CSharpParseOptions.Default.WithKind(Microsoft.CodeAnalysis.SourceCodeKind.Script);
var expression = CSharpSyntaxTree.ParseText(input, options).GetRoot().DescendantNodes().OfType<ExpressionStatementSyntax>().FirstOrDefault()?.Expression;
Console.WriteLine(EvaluateExpression(expression));
}
Complex EvaluateExpression(ExpressionSyntax expr)
{
if (expr is BinaryExpressionSyntax)
{
var binExpr = (BinaryExpressionSyntax)expr;
var left = EvaluateExpression(binExpr.Left);
var right = EvaluateExpression(binExpr.Right);
switch (binExpr.OperatorToken.ValueText)
{
case "+":
return left + right;
case "-":
return left - right;
case "*":
return left * right;
case "/":
return left / right;
default:
throw new NotSupportedException(binExpr.OperatorToken.ValueText);
}
}
else if (expr is IdentifierNameSyntax)
{
return GetValue(((IdentifierNameSyntax)expr).Identifier.ValueText);
}
else if (expr is LiteralExpressionSyntax)
{
var value = ((LiteralExpressionSyntax)expr).Token.Value;
return float.Parse(value.ToString());
}
else if (expr is InvocationExpressionSyntax)
{
var invocExpr = (InvocationExpressionSyntax)expr;
var args = invocExpr.ArgumentList.Arguments.Select(arg => EvaluateExpression(arg.Expression)).ToArray();
return Call(((IdentifierNameSyntax)invocExpr.Expression).Identifier.ValueText, args);
}
else
throw new NotSupportedException(expr.GetType().Name);
}
Complex Call(string identifier, Complex[] args)
{
switch (identifier.ToLower())
{
case "sin":
return Complex.Sin(args[0]);
default:
throw new NotImplementedException(identifier);
}
}
Complex GetValue(string identifier)
{
switch (identifier)
{
case "x":
return new Complex(1, 0);
case "y":
return new Complex(0, 1);
default:
throw new ArgumentException("Identifier not found", nameof(identifier));
}
}
I've found similar questions asked before but the answers I've seen have been specific to the example given by the person or workarounds for that person's example, not a general solution.
I'd like to pass a class' property to a function to do an operation on that property. The example I'm going to use is incrementing a value, but I have more complicated scenarios so I'm looking for a general solution, not an answer for specifically incrementing.
How I used to do it is I'd either have multiple functions IncrementPassengerCount, IncrementDistanceTravelled, IncrementPlaneAge, but that's unweildly and horrible.
I'd like one general function that I can call using something like this pseudocode:
Increment(myPlane, myPlane.DistanceTravelled);
Increment(myPlane, myPlane.PlaneAge);
//where
public void Increment(Airplane myPlane, Property propToIncrement)
{
myPlane.propToIncrement++; //or do whatever like I now have myPlane.DistanceTravelled
}
I've tried this:
Increment(myPlane, x => x.DistanceTravelled);
//where
public void Increment(Airplane myPlane, Func<Log, IComparable> property)
{
property(myPlane)++;
}
But this causes a
Operator '++' cannot be applied to operand of type 'System.IComparable'
Is there a way to do what I'm imagining or am I looking at it wrong? Thanks in advance.
Is is possible, though convoluted and probably a sign that you should perhaps do it a different way, but here it is. (I would recommend as Jon Skeet mentioned, to just use the ++ operator instead of invoking the Increment method. In addition to the method I included two classes that will allow you to test the code in a console app. There would need to be plenty of error checking. I have a few null checks, but there may be more locations it is needed. If you have overloaded the ++ operator, it works for those types too, but any errors cannot be anticipated.
public static void Increment(this object o, string propertyName)
{
var property = o.GetType().GetProperty(propertyName);
if (property == null)
return;
var val = property.GetValue(o, null);
var op_Inc = o.GetType().GetMethod("op_Increment");
if(op_Inc != null)
{
var val2 = op_Inc.Invoke(val, null);
property.SetValue(o,val2);
}
switch (Type.GetTypeCode(property.PropertyType))
{
case TypeCode.UInt16:
{
var x = (UInt16)val;
x++;
property.SetValue(o, x);
}
break;
case TypeCode.UInt32:
{
var x = (UInt32)val;
x++;
property.SetValue(o, x);
}
break;
case TypeCode.UInt64:
{
var x = (UInt64)val;
x++;
property.SetValue(o, x);
}
break;
case TypeCode.Int16:
{
var x = (Int16)val;
x++;
property.SetValue(o, x);
}
break;
case TypeCode.Int32:
{
var x = (Int32)val;
x++;
property.SetValue(o, x);
}
break;
case TypeCode.Int64:
{
var x = (Int64)val;
x++;
property.SetValue(o, x);
}
break;
case TypeCode.Decimal:
{
var x = (Decimal)val;
x++;
property.SetValue(o, x);
}
break;
case TypeCode.Double:
{
var x = (Double)val;
x++;
property.SetValue(o, x);
}
break;
case TypeCode.Single:
{
var x = (Single)val;
x++;
property.SetValue(o, x);
}
break;
}
}
}
public class Example
{
public static void Main()
{
var plane = new Plane(){DistanceTravelled = 0, PlaneAge = 0};
Console.WriteLine("Before invoking increment: dist = {0}, age = {1}", plane.DistanceTravelled, plane.PlaneAge);
plane.Increment("DistanceTravelled");
plane.Increment("PlaneAge");
Console.WriteLine("After invoking increment: dist = {0}, age = {1}", plane.DistanceTravelled, plane.PlaneAge);
Console.ReadKey();
}
}
public class Plane
{
public int DistanceTravelled { get; set; }
public int PlaneAge { get; set; }
}