C# Delegates. Casting not working for some reason - c#

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.

Related

Creating List from JSON response [duplicate]

I have two classes, one for defining the algorithm parameters and another to implement the algorithm:
Class 1 (algorithm parameters):
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace VM_Placement
{
public static class AlgorithmParameters
{
public static int pop_size = 100;
public static double crossover_rate = 0.7;
public static double mutation_rate = 0.001;
public static int chromo_length = 300;
public static int gene_length = 4;
public static int max_allowable_generations = 400;
static Random rand = new Random();
public static double random_num = rand.NextDouble();
}
}
Class 2 (implement algorithm):
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace VM_Placement
{
public class Program
{
public struct chromo_typ
{
public string bits;
public float fitness;
//public chromo_typ(){
// bits = "";
// fitness = 0.0f;
//}
chromo_typ(string bts, float ftns)
{
bits = bts;
fitness = ftns;
}
};
public static int GetRandomSeed()
{
byte[] bytes = new byte[4];
System.Security.Cryptography.RNGCryptoServiceProvider rng =
new System.Security.Cryptography.RNGCryptoServiceProvider();
rng.GetBytes(bytes);
return BitConverter.ToInt32(bytes, 0);
}
public string GetRandomBits()
{
string bits="";
for (int i = 0; i < VM_Placement.AlgorithmParameters.chromo_length; i++)
{
if (VM_Placement.AlgorithmParameters.random_num > 0.5f)
bits += "1";
else
bits += "0";
}
return bits;
}
public static void Main(string[] args)
{
Random rnd = new Random(GetRandomSeed());
while (true)
{
chromo_typ[] Population = new chromo_typ[VM_Placement.AlgorithmParameters.pop_size];
double Target;
Console.WriteLine("\n Input a target number");
Target = Convert.ToDouble(Console.ReadLine());
for (int i = 0; i < VM_Placement.AlgorithmParameters.pop_size; i++)
{
Population[i].bits = GetRandomBits();
Population[i].fitness = 0.0f;
}
}
}
}
}
I am getting an error on Population[i].bits = GetRandomBits(); in Main().
Error is:
An object reference is required for the non-static field, method, or property 'VM_Placement.Program.GetRandomBits()'
Am I missing anything?
The Main method is Static. You can not invoke a non-static method from a static method.
GetRandomBits()
is not a static method. Either you have to create an instance of Program
Program p = new Program();
p.GetRandomBits();
or make
GetRandomBits() static.
It looks like you want:
public static string GetRandomBits()
Without static, you would need an object before you can call the GetRandomBits() method. However, since the implementation of GetRandomBits() does not depend on the state of any Program object, it's best to declare it static.
The Main method is static inside the Program class. You can't call an instance method from inside a static method, which is why you're getting the error.
To fix it you just need to make your GetRandomBits() method static as well.

Im referencing a constant class static variables, but when i do the values somehow change

Here is my constant class that i reference from.
Below that is the class that is trying to use the reference.
Here is the error message im getting.
The Type initializer for ConstantClass threw an exception ---> System.OverflowException: Value was either too large or too small for a Decimal.
Any ideas about it?
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace UnitTests
{
[TestClass]
public static class ConstantClass
{
public static int positiveInt = 10;
public static int negativeInt = -10;
public static long positivePastLimitInt = unchecked((int)2147483648);
public static long negativePastLimitInt = unchecked((int)-2147483649);
public static int zeroInt = 0;
public static char lowerChar = 'c';
public static char spaceChar = ' ';
public static char symbolChar = '#';
public static char numberChar = '1';
public static char upperChar = 'D';
public static string lowerString = "hello";
public static string upperString = "HELLO";
public static string emptyString = "";
public static string spaceString = " ";
public static string tabString = " ";
public static string symbolString = "!^&";
public static string nullString = null;
public static short positiveShort = 10;
public static short negativeShort = -10;
public static short zeroShort = 0;
public static int positivePastLimitShort = unchecked((short)32768);
public static int negativePastLimitShort = unchecked((short)-32769);
public static long positiveLong = 10;
public static long negativeLong = -10;
public static long zeroLong = 0;
public static Int64 positivePastLimitLong = (long)2147483648;
public static Int64 negativePastLimitLong = (long)-2147483649;
public static double positiveDouble = 10.0;
public static double negativeDouble = -10.0;
public static double zeroDouble = 0.0;
public static double positiveLimitDouble = double.MaxValue;
public static double negativeLimitDouble = double.MinValue;
public static float positiveFloat = 10.0F;
public static float negativeFloat = -10.0F;
public static float zeroFloat = 0.0F;
public static double positivePastLimitFloat = (float)float.MaxValue + 1;
public static double negativePastLimitFloat = (float)float.MinValue - 1;
public static bool positiveBool = true;
public static bool negativeBool = false;
//Here is the variable im trying to use.
public static decimal positiveDecimal = 10.0m;
public static decimal negativeDecimal = -10.0m;
public static decimal zeroDecimal = 0.0m;
public static decimal positivePastLimitDecimal = Convert.ToDecimal(80000000000000E+40);
public static decimal negativePastLimitDecimal = Convert.ToDecimal(-8000000000000E-40);
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace UnitTests
{
[TestClass]
public class ByteDecimalTests
{
/// <summary>
///
/// </summary>
[TestMethod]
public void DecimalToBytes_WhenDecimalIsPositive()
{
//This is where i reference the constant class
Decimal positiveDecimal = ConstantClass.positiveDecimal;
//Decimal positiveDecimal = 12.98m;
String positiveDecimalString = positiveDecimal.ToString();
byte[] positiveDecimalArray = Encoding.ASCII.GetBytes(positiveDecimalString);
byte[] array = ByteDecimal.DecimalToBytes(positiveDecimal);
System.Diagnostics.Debug.WriteLine(Encoding.Default.GetString(positiveDecimalArray));
System.Diagnostics.Debug.WriteLine(Encoding.Default.GetString(array));
Assert.AreEqual(array, positiveDecimalArray);
}
}
}
Your problem is here:
public static decimal positivePastLimitDecimal = Convert.ToDecimal(80000000000000E+40)
public static decimal negativePastLimitDecimal = Convert.ToDecimal(-8000000000000E-40);
You cannot store such big numbers on a decimal. Use float or double for that.
The maximum value you can store in a decimal is: 79,228,162,514,264,337,593,543,950,335.
Maybe this helps you to understand what you are doing, and so you could decide how to solve it. I'll take the short as the easier case to study, but the same can be said for every other case.
From your code:
public static int positivePastLimitShort = unchecked((short)32768);
A short is internally stored as a 16 bits value, 15 bits for data and 1 bit for the sign.
sign b14 b13 b12 b11 b10 b09 b08 b07 b06 b05 b04 b03 b02 b01 b00
When you try to use a value that needs more than 15 bits to be represented, an overflow will occur.
32768 in binary form is 1000000000000000
but you cannot use the bit15, which is reserved for the sign in shorts (in ushort you can use all 16 bits, as no bit is reserved for sign).
You could even supress the cast and the unchecked, and just do:
public static int positivePastLimitShort = 32768;
as an int uses internally 32 bits, 1 for sign and 31 for data.
This is working as you have a value type that can store bigger numbers.
So, using an int for shorts passing the limit, using long for ints passing the limits, and so on. The problem would be to handle numbers passing the limits of the bigger capacity types, as long, double or decimal. For these cases you need a different way.

Result is getting 0 when using Operator Overloading in 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.

Cannot serialize type 'TickDataDefinition.data' because it does not have any serializable fields nor properties

I get this error when I tried to declare the serializer as below. It returns the error which I do not understand what it means.
var serializer = MsgPack.Serialization.MessagePackSerializer.Create<data>();
Below is the class definition.
using System;
using System.Collections.Generic;
using System.Text;
namespace TickDataDefinition
{
class data
{
private enum type { trade, quote }
private long time;
private double bid1;
private double ask1;
private double bidsize;
private double asksize;
private double price;
private uint size;
public data()
{
}
public data(long t, double b, double a, double bs, double ask)
{
time = t;
bid1 = b;
ask1 = a;
bidsize = bs;
asksize = ask;
}
public data(long t, double p, uint s)
{
time = t;
price = p;
size = s;
}
}
}
All of the elements of that class are private other than constructors (which can't be serialized anyway, and wouldn't make sense if so). Expose some actually accessible elements and serialize.

C# error: "An object reference is required for the non-static field, method, or property"

I have two classes, one for defining the algorithm parameters and another to implement the algorithm:
Class 1 (algorithm parameters):
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace VM_Placement
{
public static class AlgorithmParameters
{
public static int pop_size = 100;
public static double crossover_rate = 0.7;
public static double mutation_rate = 0.001;
public static int chromo_length = 300;
public static int gene_length = 4;
public static int max_allowable_generations = 400;
static Random rand = new Random();
public static double random_num = rand.NextDouble();
}
}
Class 2 (implement algorithm):
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace VM_Placement
{
public class Program
{
public struct chromo_typ
{
public string bits;
public float fitness;
//public chromo_typ(){
// bits = "";
// fitness = 0.0f;
//}
chromo_typ(string bts, float ftns)
{
bits = bts;
fitness = ftns;
}
};
public static int GetRandomSeed()
{
byte[] bytes = new byte[4];
System.Security.Cryptography.RNGCryptoServiceProvider rng =
new System.Security.Cryptography.RNGCryptoServiceProvider();
rng.GetBytes(bytes);
return BitConverter.ToInt32(bytes, 0);
}
public string GetRandomBits()
{
string bits="";
for (int i = 0; i < VM_Placement.AlgorithmParameters.chromo_length; i++)
{
if (VM_Placement.AlgorithmParameters.random_num > 0.5f)
bits += "1";
else
bits += "0";
}
return bits;
}
public static void Main(string[] args)
{
Random rnd = new Random(GetRandomSeed());
while (true)
{
chromo_typ[] Population = new chromo_typ[VM_Placement.AlgorithmParameters.pop_size];
double Target;
Console.WriteLine("\n Input a target number");
Target = Convert.ToDouble(Console.ReadLine());
for (int i = 0; i < VM_Placement.AlgorithmParameters.pop_size; i++)
{
Population[i].bits = GetRandomBits();
Population[i].fitness = 0.0f;
}
}
}
}
}
I am getting an error on Population[i].bits = GetRandomBits(); in Main().
Error is:
An object reference is required for the non-static field, method, or property 'VM_Placement.Program.GetRandomBits()'
Am I missing anything?
The Main method is Static. You can not invoke a non-static method from a static method.
GetRandomBits()
is not a static method. Either you have to create an instance of Program
Program p = new Program();
p.GetRandomBits();
or make
GetRandomBits() static.
It looks like you want:
public static string GetRandomBits()
Without static, you would need an object before you can call the GetRandomBits() method. However, since the implementation of GetRandomBits() does not depend on the state of any Program object, it's best to declare it static.
The Main method is static inside the Program class. You can't call an instance method from inside a static method, which is why you're getting the error.
To fix it you just need to make your GetRandomBits() method static as well.

Categories

Resources