I need to overload a method for it to be able to calculate the area of a circle, square, rectangle, triangle and a trapezoid. I think I've got them all figured out but the circle seems to be a problem.
static void Pole(int x, double y = 3.14)
{
Console.WriteLine(x * x * y);
}
static int Pole(int x)
{
return x * x;
}
static int Pole(int x, int y)
{
return x * y;
}
static int Pole(int x, int y, int z = 2)
{
return x * y / z;
}
static int Pole(int x, int y, int v, int z = 2)
{
return (x + y) / z * v;
}
static void Main(string[] args)
{
int x = 2;
int y = 3.14;
Console.WriteLine(Pole(x, y));
Console.ReadKey();
I don't know what problem you're getting, but I can probably guess it's one of the following:
1) You're getting an error because one of your overload methods is returning void while the others are returning int (they all have to be the same)
or
2) What your Main method is calling is this method static int Pole(int x, int y) and not static void Pole(int x, double y = 3.14), which I'm assuming is the "Circle"; because you're passing in two ints instead of one int and one double.
Have you tried changing int to double for y in your Main method?
static void Main(string[] args)
{
int x = 2;
double y = 3.14;
Console.WriteLine(Pole(x, y));
Console.ReadKey();
}
also why dont you just pass in one parameter and have it multiply by 3.14 for the Pole overload method that's tasked with calculating the circle?
/// <summary>
/// Method to calculate a circle
/// </summary>
/// <param name="x"></param>
/// <returns></returns>
static double Pole(int x)
{
return 3.14(x * x);
}
static void Main(string[] args)
{
int x = 2;
Console.WriteLine(Pole(x));
Console.ReadKey();
}
Another tip: add some notes in your code. You have 5 methods named Pole, one accepting one more int parameter than the last one and each of the 5 methods are calculating for a different shape.
Adding a summary to each method or just a simple comment will help you and anyone else trying to read your code, moving forward.
Important: Because these are overloads, you're going to need to change all your methods to return double instead of int just for the sake of the "Circle" Pole method. Having it as the only void method was probably causing the error for you to begin with.
This should be enough to get you started:
//Circle
static double Pole(int x, double y)
{
if(y != 3.14)
y = 3.14;
return y(x * x);
}
//Square
static double Pole(int x)
{
return x * x;
}
//Rectangle
static double Pole(int x, int y)
{
return x * y;
}
//Triangle
static double Pole(int x, int y, int z)
{
if(z != 2)
z = 2;
return x * y / z;
}
//Trapezoid
static double Pole(int x, int y, int v, int z)
{
if(z != 2)
z = 2;
return (x + y) / z * v;
}
static void Main(string[] args)
{
int x = 2;
double y = 3.14;
Console.WriteLine(Pole(x, y));
Console.ReadKey();
}
Related
I have this code:
public void myMethod()
{
int a = 10;
int b = 20;
Func<int, int, int> multiplyDelegate;
multiplyDelegate = Multiply;
multiplyDelegate += Multiply2;
Console.WriteLine(multiplyDelegate(a,b));
}
public int Multiply(int x, int y)
{
return x * y;
}
public int Multiply2(int x, int y)
{
return x * y + 10;
}
By running myMethod, I expect the console to show the returns from both methods "Multiply" and "Multiply2" but only the return from the method "Multiply2" is shown. Have I done something wrong here or have I misunderstood the concept of delegates? From what I've learned a delegate is an array of references to methods.
From Using Delegates (C# Programming Guide):
If the delegate has a return value and/or out parameters, it returns
the return value and parameters of the last method invoked.
You are right delegate can store methods and invoke multiple methods at once. It will return the last one except if you explicitly Invoke them.
Using your code, here is an example of explicite Invoke for all of your collection of methods.
var results = multiplyDelegate.GetInvocationList().Select(x => (int)x.DynamicInvoke(10, 20));
foreach (var result in results)
Console.WriteLine(result);
EDIT :
This will work for function Func and not Action. Here is an example supposing it's an Action
foreach (Delegate action in multiplyDelegate.GetInvocationList())
{
action.DynamicInvoke(10, 20);
// Do Something
}
This second example work for Func as well.
I don't have any official sources for this, but I think what is happening is that you can't return two values from one delegate call. Therefore, the last value returned is used.
Although only the last return value is used, the two methods are indeed executed. We can prove this by printing some stuff before we return:
public int Multiply(int x, int y)
{
Console.WriteLine("Hello1");
return x * y;
}
public int Multiply2(int x, int y)
{
Console.WriteLine("Hello2");
return x * y + 10;
}
Both Hello1 and Hello2 are printed.
Only one object can be returned and since Multiple2 is the last to execute it get's outputted in the console.
There isnt a way to change that.
You could do:
public void myMethod()
{
int a = 10;
int b = 20;
Action<int, int> multiplyDelegate;
multiplyDelegate = Multiply;
multiplyDelegate += Multiply2;
multiplyDelegate(10, 20);
Console.Read();
}
public void Multiply(int x, int y)
{
Console.WriteLine(x * 2);
}
public void Multiply2(int x, int y)
{
Console.WriteLine(x * y + 10);
}
I had this question too and test several things like another way of setting method to the delegate but finally only usable way is to write another line after each set:
public void myMethod()
{
int a = 10;
int b = 20;
Func<int, int, int> multiplyDelegate;
multiplyDelegate = Multiply;
Console.WriteLine(multiplyDelegate(a,b));
multiplyDelegate += Multiply2;
Console.WriteLine(multiplyDelegate(a,b));
}
public int Multiply(int x, int y)
{
return x * y;
}
public int Multiply2(int x, int y)
{
return x * y + 10;
}
I do not want to declare x variable but I wanna increment out y. Is it possible? Albahari code. The problem is y=1 is always initializing. I want to check if y exists then y = y + 1; and y = 0 otherwise. wanna access and increment variable created via out not by me.
using System;
namespace ConsoleAppX
{
class D
{
static void Foo(out int y)
{
y = 1;
y = y + 1; // Mutate y
}
// static int x;
static void Main(string[] args)
{
Foo(out int x);
Foo(out x);
Foo(out x);
Console.WriteLine(x);
Console.ReadLine();
}
}
}
Dont know what you are trying do :)
But Out method required Parameter to assign some value.
If you dont want assign any value and Just Manipulate the passed value
You can use ref
So your code may look like,
using System;
namespace ConsoleAppX
{
class D
{
static void Foo(ref int y)
{
//y = 1;
y = y + 1; // Mutate y
}
// static int x;
static void Main(string[] args)
{
int x = 0;
Foo(ref x);
Foo(ref x);
Foo(ref x);
Console.WriteLine(x);
Console.ReadLine();
}
}
}
I have this code:
public void myMethod()
{
int a = 10;
int b = 20;
Func<int, int, int> multiplyDelegate;
multiplyDelegate = Multiply;
multiplyDelegate += Multiply2;
Console.WriteLine(multiplyDelegate(a,b));
}
public int Multiply(int x, int y)
{
return x * y;
}
public int Multiply2(int x, int y)
{
return x * y + 10;
}
By running myMethod, I expect the console to show the returns from both methods "Multiply" and "Multiply2" but only the return from the method "Multiply2" is shown. Have I done something wrong here or have I misunderstood the concept of delegates? From what I've learned a delegate is an array of references to methods.
From Using Delegates (C# Programming Guide):
If the delegate has a return value and/or out parameters, it returns
the return value and parameters of the last method invoked.
You are right delegate can store methods and invoke multiple methods at once. It will return the last one except if you explicitly Invoke them.
Using your code, here is an example of explicite Invoke for all of your collection of methods.
var results = multiplyDelegate.GetInvocationList().Select(x => (int)x.DynamicInvoke(10, 20));
foreach (var result in results)
Console.WriteLine(result);
EDIT :
This will work for function Func and not Action. Here is an example supposing it's an Action
foreach (Delegate action in multiplyDelegate.GetInvocationList())
{
action.DynamicInvoke(10, 20);
// Do Something
}
This second example work for Func as well.
I don't have any official sources for this, but I think what is happening is that you can't return two values from one delegate call. Therefore, the last value returned is used.
Although only the last return value is used, the two methods are indeed executed. We can prove this by printing some stuff before we return:
public int Multiply(int x, int y)
{
Console.WriteLine("Hello1");
return x * y;
}
public int Multiply2(int x, int y)
{
Console.WriteLine("Hello2");
return x * y + 10;
}
Both Hello1 and Hello2 are printed.
Only one object can be returned and since Multiple2 is the last to execute it get's outputted in the console.
There isnt a way to change that.
You could do:
public void myMethod()
{
int a = 10;
int b = 20;
Action<int, int> multiplyDelegate;
multiplyDelegate = Multiply;
multiplyDelegate += Multiply2;
multiplyDelegate(10, 20);
Console.Read();
}
public void Multiply(int x, int y)
{
Console.WriteLine(x * 2);
}
public void Multiply2(int x, int y)
{
Console.WriteLine(x * y + 10);
}
I had this question too and test several things like another way of setting method to the delegate but finally only usable way is to write another line after each set:
public void myMethod()
{
int a = 10;
int b = 20;
Func<int, int, int> multiplyDelegate;
multiplyDelegate = Multiply;
Console.WriteLine(multiplyDelegate(a,b));
multiplyDelegate += Multiply2;
Console.WriteLine(multiplyDelegate(a,b));
}
public int Multiply(int x, int y)
{
return x * y;
}
public int Multiply2(int x, int y)
{
return x * y + 10;
}
I guess, it's a pretty basic problem, but I couldn't find an answer.
Program is made for learning purpose, I'd defined a vector class with multiplication operator like this:
public class vector
{
private int x;
private int y;
public vector(int x,int y)
{
this.x = x;
this.y = y;
}
public static vector operator *(vector w1, vector w2)
{
return int w1.x*w2.x + w1.y * w2.y;
}
}
The problem is that visual studio underlines the expression in return, how should I modify the definition of "*" operator to make it work ?
You defined your function to return a vector, however you are only returning an int.
public static vector operator *(vector w1, vector w2)
{
return int w1.x*w2.x + w1.y * w2.y;
}
should be
public static int operator *(vector w1, vector w2)
{
return int (w1.x*w2.x + w1.y * w2.y);
}
Or for example, if you wanted to return a vector for the addition operator, that would look like:
public static vector operator +(vector w1, vector w2)
{
return new vector (w1.x+w2.x, w1.y + w2.y);
}
You need to return a new instance of vector, try this:
public class vector
{
private int x;
private int y;
public vector(int x, int y)
{
this.x = x;
this.y = y;
}
public static vector operator *(vector w1, vector w2)
{
return new vector(w1.x* w2.x, w1.y * w2.y);
}
}
int a, b, c;
Constructor()
{
a = 5;
b = 10;
c = 15;
//do stuff
}
Constructor(int x, int y)
{
a = x;
b = y;
c = 15;
//do stuff
}
Constructor(int x, int y, int z)
{
a = x;
b = y;
c = z;
//do stuff
}
To prevent duplication of "stuff" and a few assignments, I tried out something like:
int a, b, c;
Constructor(): this(5, 10, 15)
{
}
Constructor(int x, int y): this(x, y, 15)
{
}
Constructor(int x, int y, int z)
{
a = x;
b = y;
c = z;
//do stuff
}
This works for what I want to do, but sometimes I need to use some lengthy code to create new objects or do some calculations:
int a, b, c;
Constructor(): this(new Something(new AnotherThing(param1, param2, param3),
10, 15).CollectionOfStuff.Count, new SomethingElse("some string", "another
string").GetValue(), (int)Math.Floor(533 / 39.384))
{
}
Constructor(int x, int y): this(x, y, (int)Math.Floor(533 / 39.384))
{
}
Constructor(int x, int y, int z)
{
a = x;
b = y;
c = z;
//do stuff
}
This code is pretty much the same as before, only the parameters that are being passed aren't very readable. I would prefer doing something like:
int a, b, c;
Constructor(): this(x, y, z) //compile error, variables do not exist in context
{
AnotherThing at = new AnotherThing(param1, param2, param3);
Something st = new Something(aThing, 10, 15)
SomethingElse ste = new SomethingElse("some string", "another string");
int x = thing.CollectionOfStuff.Count;
int y = ste.GetValue();
int z = (int)Math.Floor(533 / 39.384);
//In Java, I think you can call this(x, y, z) at this point.
this(x, y, z); //compile error, method name expected
}
Constructor(int x, int y): this(x, y, z) //compile error
{
int z = (int)Math.Floor(533 / 39.384);
}
Constructor(int x, int y, int z)
{
a = x;
b = y;
c = z;
//do stuff
}
Basically I'm building the parameters within the constructor body. Then I'm trying to pass those built parameters to another constructor. I think I remember being able to use the "this" and "super" keywords to call constructors while inside the body of another constructor when coding in Java. It doesn't seem possible in C#.
Is there a way to do this easily? Did I do something incorrectly? If this is not possible, should I just stick with the unreadable code?
I guess I could always cut the duplicated code into another method completely outside the constructors. Then each constructor would just do its own thing and call the code shared by the other constructors.
As an alternative to calling an initialization method from all constructors (which prevents you from using readonly fields) or factory methods (which introduce additional complexity when you have derived classes), you can use a parameter object:
int a, b, c;
public Constructor()
: this(new ConstructorParameters())
{
}
public Constructor(int x, int y)
: this(new ConstructorParameters(x, y))
{
}
public Constructor(int x, int y, int z)
{
a = x;
b = y;
c = z;
//do stuff
}
private Constructor(ConstructorParameters parameters)
: this(parameters.X, parameters.Y, parameters.Z)
{
}
private class ConstructorParameters
{
public int X;
public int Y;
public int Z;
public ConstructorParameters()
{
AnotherThing at = new AnotherThing(param1, param2, param3);
Something st = new Something(at, 10, 15)
SomethingElse ste = new SomethingElse("some string", "another string");
X = st.CollectionOfStuff.Count;
Y = ste.GetValue();
Z = (int)Math.Floor(533 / 39.384);
}
public ConstructorParameters(int x, int y)
{
X = x;
Y = y;
Z = (int)Math.Floor(533 / 39.384);
}
}
You can do
Constructor() : this(5, 10, 15)
{
}
Constructor(int x, int y) : this(x, y, 15)
{
}
Constructor(int x, int y, int z)
{
int a = x;
int b = y;
int c = z;
//do stuff
}
However if you need to do some fancy logic depending on the parameters, I would use a factory pattern:
public class myclass
{
private myclass(int x, int y, int z)
{
int a = x;
int b = y;
int c = z;
//do stuff
}
public static myclass Create()
{
AnotherThing at = new AnotherThing(param1, param2, param3);
Something st = new Something(aThing, 10, 15)
SomethingElse ste = new SomethingElse("some string", "another string");
int x = thing.CollectionOfStuff.Count;
int y = ste.GetValue();
int z = (int)Math.Floor(533 / 39.384);
return new myclass(x, y ,z);
}
public static myclass Create(int x, int y)
{
if (x = 1)
return new myclass(x, y, 2)
else
return new myclass(x, y, 15);
}
public static myclass Create(int x, int y, int z)
{
//so on and so forth
return new myclass(x, y, z);
}
}
Although you don't need a factory pattern, it definitely makes your constructor logic readable.