Result is getting 0 when using Operator Overloading in C# - c#

Hi I have the below program and i am new to C#,
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace UnaryOperatorOverLoad
{
public class UnaryOperator
{
private int Number1;
private int Number2;
private int Result;
public UnaryOperator() { }
public UnaryOperator(int number1, int number2)
{
Number1 = number1;
Number2 = number2;
}
public static UnaryOperator operator +(UnaryOperator opr)
{
UnaryOperator obj = new UnaryOperator();
obj.Result = obj.Number1 + obj.Number2;
return obj;
}
public void showdata()
{
Console.WriteLine("The Sum of Two Numbers is : " + Result);
}
}
public class Program
{
static void Main(string[] args)
{
UnaryOperator opr = new UnaryOperator(20, 30);
opr.showdata();
Console.ReadLine();
}
}
}
When i execute the code , i am getting the result is 0. I am not sure where i went wrong.Please help me to rectify the code.

Your mistakes:
You are creating new UnaryOperator obj = new UnaryOperator(); in operator overloading function. So obj.Number1 and obj.Number2 's value is 0, because you have just created obj instance.
You are never calling the + operator. Add opr = +opr; statement in to the Main method.
Change your code as:
public class UnaryOperator
{
private int Number1;
private int Number2;
private int Result;
public UnaryOperator() { }
public UnaryOperator(int number1, int number2)
{
Number1 = number1;
Number2 = number2;
}
public static UnaryOperator operator +(UnaryOperator opr)
{
opr.Result = opr.Number1 + opr.Number2; // Change this line
return opr;
}
public void showdata()
{
Console.WriteLine("The Sum of Two Numbers is : " + Result);
}
}
public class Program
{
static void Main(string[] args)
{
UnaryOperator opr = new UnaryOperator(20, 30);
opr = +opr; // Add this statement
opr.showdata();
Console.ReadLine();
}
}

This line of code
UnaryOperator opr = new UnaryOperator(20, 30);
Creates a new UnaryOPerator objcet and sets the Number1 and Number2 equal to 20 and 30 correspondingly.
Then you call opr.showdata();, which will print the value of the Result variable to the console. However, since you haven't performed any addition, the value of the variable would be the default, 0. That's the reason why you got 0.
Side note: I can't get why you are tyring to overload the addition the way you do it. It's reasonable to want to overload the addition of two custom objects, like UnaryOperator. However it's seems to me a bit strange that you are trying to overload the addition using the way you do it. Also, since the + operator has two operands, you have to define them like below (that's may not the overload you thought about, but this is the proper form in general terms):
public static UnaryOperator operator +(UnaryOperator unaryOperator1, UnaryOperator unaryOperator2)
{
return new UnaryOperator(unaryOperator1.Number1+unaryOperator2.Number1,
unaryOperator1.Number2+UnaryOperator2.Number2);
}
In order for this work, you would have to change the definition of your class to the following one:
public class UnaryOperator
{
public int Number1 { get; set; }
public int Number2 { get; set; }
public UnaryOperator(int number1, int number2)
{
Number1 = number1;
Number2 = number2;
}
public static UnaryOperator operator +(UnaryOperator unaryOperator1, UnaryOperator unaryOperator2)
{
return new UnaryOperator(unaryOperator1.Number1+unaryOperator2.Number1,
unaryOperator1.Number2+unaryOperator2.Number2);
}
public void ShowData()
{
Console.WriteLine("Number1: {0}, Number2: {1}", Number1, Number2);
}
}
The the Main method should change to the following one:
public class Program
{
static void Main(string[] args)
{
// Declare the first UnaryOperator object.
UnaryOperator opr1 = new UnaryOperator(20, 30);
// Declare the second UnaryOperator object.
UnaryOperator opr2 = new UnaryOperator(10, 40);
// Add them using the overloaded version of the + operator
UnaryOperator result = opr1+opr2;
// Show the results
result.ShowData();
Console.ReadLine();
}
}
As I stated above, this may not be exactly the version of your + operator overload, but I wrote an implementation of this overload to see it how it works. For further documentation, please look here.

Related

Problem with variables while trying to make a c# library(.dll)

I want to make a library that sums 2 numbers(a and b) and then stores the value into a result variable inside a library(.dll).
I tried this:
public static void Sum(int number1, int number2, int result)
{
result = number1 + number2;
}
but I can't make it so that in a program that uses this library, you can get the value of the result value that this function calculates and that's what I couldn't figure out for the past days. If you need any more info I will gladly provide it to you! Hope someone can help me!
In your case you do not return any result, consider using some of the following:
public static void Main()
{
var sumRes = SumResut(1, 2);
Console.WriteLine($"SumResult = {sumRes}");
OutSum(1, 2, out int outRes);
Console.WriteLine($"OutSum = {outRes}");
int refRes = 0;
RefSum(1, 2, ref refRes);
Console.WriteLine($"RefSum = {refRes}");
}
public static int SumResut(int number1, int number2)
{
return number1 + number2;
}
public static void OutSum(int number1, int number2, out int result)
{
result = number1 + number2;
}
public static void RefSum(int number1, int number2, ref int result)
{
result = number1 + number2;
}

How to add a second argument(Number) to a calculator program?

I'm working on a small calculator program in Unity.
I only need the calculator to work with two numbers.
The feature I'm trying to implement:
After inputting the math operator, It should display the second number in the third index.
The issue:
Instead of Adding a second number, the first number is being overwritten if a different number is pressed on the keyboard.
Here's the script I've created:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class Functions : MonoBehaviour
{
// Global Variable to display text on top panel
public Text panelText;
// Create a number variable
string num;
string num1;
string num2;
string mOpr;
string calNum;
string cbutton;
string opr;
bool isFirstNum;
// Start is called before the first frame update
void Start()
{
}
// A function with an int argument
public void NumberInputOne(string num)
{
num1 = num;
num2 = num;
if (panelText.text.Length < 1)
{
Debug.Log(num1);
panelText.text = num1;
isFirstNum = false;
}
else if (panelText.text.Length > 1 && panelText.text.Length < 3)
{
num2 = num;
Debug.Log(num2);
panelText.text = num1 + mOpr + num2;
}
}
public void OperatorInput(string opr)
{
mOpr = opr;
if (panelText.text.Length > 0 && panelText.text.Length < 2)
{
panelText.text = num1 + mOpr;
}
}
// public void NumberInputTwo(int num)
//{
// ResNum2 = num;
// Debug.Log(ResNum2);
// if (panelText.text.Length > 1 && panelText.text.Length < 3)
// {
// panelText.text = ResNum1 + opr + ResNum2;
// }
// }
public void RestartCal(string cButton)
{
panelText.text = "";
}
}
I've also added a screen recording to capture the issue:
First number being overwritten
Do you have any suggestions?
Thank you
use the NumberInputOne func like below;
public void NumberInputOne(string num)
{
if (num1 is null)
{
Debug.Log(num1);
panelText.text = num1;
num1 = num
}
else
{
num2 = num;
Debug.Log(num2);
panelText.text = num1 + mOpr + num2;
}
}
btw i recommend that you review the sample calculation application codes. because apart from what you're asking, there are places you need to improve in general.
This feels like a beginner programming exercise. But the right way to build a calculator involves programming concepts that you probably haven't been taught yet. Which makes this a poor choice as an assignment.
Personally I would build a calculator by defining a simple syntax tree to represent the formula being input. Including methods to display the formula and calculate the answer. For example;
public interface IValue
{
int Calculate();
string PrintValue();
}
public class Number : IValue
{
public int? Value;
public void AddDigit(int digit) => Value = (Value ?? 0) * 10 + digit;
public int Calculate() => Value ?? 0;
public string PrintValue() => Value?.ToString();
}
public abstract class BinaryOperator : IValue
{
public IValue Left;
public IValue Right;
public abstract int Operation(int left, int right);
public abstract char Operator { get; }
public int Calculate()
{
var left = Left.Calculate();
var right = Right.Calculate();
return Operation(left, right);
}
public string PrintValue() => $"{Left?.PrintValue()} {Operator} {Right?.PrintValue()}";
}
public class Addition : BinaryOperator
{
public override char Operator => '+';
public override int Operation(int left, int right) => left + right;
}
// TODO define other operators
Then think about how each button should change the syntax tree.
// the entire formula
public IValue Root;
// the number currently being typed
public Number Input;
public void Display() {
panelText.text = Root.PrintValue();
}
// start / clear
public void Start(){
Root = Input = new Number(){
Value = 0
};
Display();
}
public void Plus(){
// left as an exercise for the reader
Display();
}
public void Digit(int digit) {
Input.AddDigit(digit);
Display();
}
public void Calculate() {
// left as an exercise for the reader
Display();
}

What is the meaning of the static field in AttemptController in following sample code ?

I am newbie in C# and trying to learn static keyword. I don't understand why we need to initialize static field twice. as my understanding static field preserve the value during the program execution.
class Program
{
static void Main(string[] args)
{
AttemptController Obj = new AttemptController(3, 2);
Console.WriteLine("Maximum: {0}", AttemptController.MaxAttempts);
Console.WriteLine("Warning: {0}", AttemptController.WarningAttempts);
Console.WriteLine("Threshold: {0}", AttemptController.Threshold);
AttemptController Obj1 = new AttemptController(7, 5);
Console.WriteLine("Maximum: {0}", AttemptController.MaxAttempts);
Console.WriteLine("Warning: {0}", AttemptController.WarningAttempts);
Console.WriteLine("Threshold: {0}", AttemptController.Threshold);
Console.ReadLine();
}
class AttemptController
{
internal static int MaxAttempts;
internal static int WarningAttempts;
internal static int Threshold;
public AttemptController(int a, int b)
{
MaxAttempts = a;
WarningAttempts = b;
Threshold = MaxAttempts - WarningAttempts;
}
}
}
So a couple of proposed changes:
make the class static
get rid of the constructor as static classes cannot have instance constructors.
add a new method called init just for demo purposes.
using System;
namespace ConsoleApp4
{
internal class Program
{
private static void Main(string[] args)
{
AttemptController.Init(3, 2);
Console.WriteLine("Maximum: {0}", AttemptController.MaxAttempts);
Console.WriteLine("Warning: {0}", AttemptController.WarningAttempts);
Console.WriteLine("Threshold: {0}", AttemptController.Threshold);
AttemptController.Init(7, 5);
Console.WriteLine("Maximum: {0}", AttemptController.MaxAttempts);
Console.WriteLine("Warning: {0}", AttemptController.WarningAttempts);
Console.WriteLine("Threshold: {0}", AttemptController.Threshold);
Console.ReadLine();
}
}
public static class AttemptController
{
internal static int MaxAttempts;
internal static int WarningAttempts;
internal static int Threshold;
public static void Init(int a, int b)
{
MaxAttempts = MaxAttempts + a;
WarningAttempts = WarningAttempts + b;
Threshold = MaxAttempts - WarningAttempts;
}
}
}
Because you set MaxAttempts,WarningAttempts,Threshold fields in the constructor method.
When you use AttemptController Obj = new AttemptController(3, 2); it will set the value.
when you use will set MaxAttempts = 3 and WarningAttempts = 2
AttemptController Obj = new AttemptController(3, 2);
when you use will set MaxAttempts = 7 and WarningAttempts = 5
AttemptController Obj1 = new AttemptController(7, 5);
static fields let all instance use the same fields value.

An object reference is required for the non-static field, method, or property DoStuff(int, int)'

using System;
using System.Collections;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
int number1,number2;
number1 = int.Parse(Console.ReadLine());
number2 = int.Parse(Console.ReadLine());
Console.WriteLine("the sum of numbers are " +" "+ (number1 + number2));
Console.ReadKey();
DoStuff(number1,number2);
}
public int DoStuff(int num1,int num2)
{
int result = num1 + num2;
return result;
}
}
}
What am I doing wrong?
You are not allowed to call a non-static method inside a static method. If you want to invoke then you need a object reference. This is because the static methods cannot be instantiate. So the method DoStuff should be static, hence its signature may looks like this:
public static int DoStuff(int num1,int num2)
{
int result = num1 + num2;
return result;
}
I have one more suggestion for you to improve your code; it is nothing but use int.TryParse instead for simple .Parse. Which helps you to handle FormatException too. So the complete code will looks like:
class Program
{
static void Main(string[] args)
{
int number1, number2;
if (int.TryParse(Console.ReadLine(), out number1) && int.TryParse(Console.ReadLine(), out number2))
{
Console.WriteLine("the sum of numbers are :{0}", DoStuff(number1, number2));
}
else
Console.ReadKey();
}
public static int DoStuff(int num1, int num2)
{
int result = num1 + num2;
return result;
}
}
You are using DoStuff as a static method.
You should do the following:
...
Console.ReadKey();
var program = new Program();
program.DoStuff(number1, number2);
...
So create an instance of your class and call the method upon it.
If you do want to use the method in a static way, you should declare it statically:
public static int DoStuff(int num1,int num2)
{
int result = num1 + num2;
return result;
}
See the "static" keyword after "public".
From C# Specifications:
1.6.6.3 Static and instance methods
A method declared with a static modifier is a static method. A static method does not operate on a
specific instance and can only directly access static members. A
method declared without a static modifier is an instance method. An
instance method operates on a specific instance and can access both
static and instance members. The instance on which an instance method
was invoked can be explicitly accessed as this. It is an error to
refer to this in a static method.
Your Main method is static, so it can only access static members. Solution is to change:
public static int DoStuff(int num1,int num2)
From a static function you can call only static functions.
So change your DoStuff function to be static:
public static int DoStuff(int num1,int num2)
{
int result = num1 + num2;
return result;
}
For more info: Static classes
A non-static member belongs to an instance. It's meaningless without somehow resolving which instance of a class you are talking about. In a static context, you don't have an instance, that's why you can't access a non-static member without explicitly mentioning an object reference.
In fact, you can access a non-static member in a static context by specifying the object reference explicitly:
class HelloWorld {
int i;
public HelloWorld(int i) { this.i = i; }
public static void Print(HelloWorld instance) {
Console.WriteLine(instance.i);
}
}
var test = new HelloWorld(1);
var test2 = new HelloWorld(2);
HelloWorld.Print(test);
Without explicitly referring to the instance in the Print method, how would it know it should print 1 and not 2?
Either you can stuff the Method with static as show in below or
public static int DoStuff(int num1,int num2)
{
int result = num1 + num2;
return result;
}
Static methods:These are called with the type name. No instance is required—this makes them slightly faster. Static methods can be public or private.
Info:
Static methods use the static keyword, usually as the first keyword or the second keyword after public.
Warning:
A static method cannot access non-static class level members. It has no "this" pointer.
Instance:
An instance method can access those members, but must be called through an instantiated object. This adds indirection.
For Example:
class Program
{
static void MethodA()
{
Console.WriteLine("Static method");
}
void MethodB()
{
Console.WriteLine("Instance method");
}
static char MethodC()
{
Console.WriteLine("Static method");
return 'C';
}
char MethodD()
{
Console.WriteLine("Instance method");
return 'D';
}
static void Main()
{
//
// Call the two static methods on the Program type.
//
Program.MethodA();
Console.WriteLine(Program.MethodC());
//
// Create a new Program instance and call the two instance methods.
//
Program programInstance = new Program();
programInstance.MethodB();
Console.WriteLine(programInstance.MethodD());
Console.ReadLine();
}
}

C# Delegates. Casting not working for some reason

2 Errors appear when I try to build this code.
First one: "Argument 2 : cannot convert from double to int."
Second one: "The best overloaded method for CalculatePay(double, int, Calculate) has some invalid arguments.
I don't understand why the casting I've applied in the BankHolidayShift and NormalShift methods isn't working. Thanks.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication8
{
public delegate int Calculate(double val1, int val2);
class PayCalculator
{
static double HourlyPay = 10;
static int HoursPerShift = 8;
static int NormalShift(double HourlyPay, int HoursPerShift)
{
return (int) HourlyPay * HoursPerShift;
}
static int BankHolidayShift(double HourlyPay, int HoursPerShift)
{
return (int)(HourlyPay * HoursPerShift) + 50;
}
public static int CalculatePay(double a, int b, Calculate calc)
{
int TotalPay = calc(a, b);
return TotalPay;
}
static void Main()
{
Calculate calc = new Calculate(BankHolidayShift);
int TotalPay = CalculatePay(HourlyPay, HourlyPay, calc);
Console.WriteLine("Total Pay for this shift is : {0}", TotalPay);
Console.ReadLine();
}
}
}
You have int TotalPay = CalculatePay(HourlyPay, HourlyPay, calc);, obviously it's a spelling, and you should have:
int TotalPay = CalculatePay(HourlyPay, HoursPerShift, calc);
BTW, local variables, as well as methods parameters, should be CamelCased.

Categories

Resources