change variable declared in out scope or access it - c#

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();
}
}
}

Related

Why does all members of a class show error 'CS0103'

I'm testing a piece of code in c# and vs2022, but I encounter some problems. I try to track the value of some members in a class, but the VS2022 shows error CS0103.
So I would like to know why VS2022 can't show their values because they are certainly in this context.
class Program
{
static void Main(string[] args)
{
ProtoType p = new ProtoType(100, 200);
p.x = 101;
p.y = 20;
int cnt = p.list.Count;
Console.ReadLine();
}
}
class ProtoType
{
public int x = 0;
public int y = 0;
public List<string> list = new List<string>();
public ProtoType(int x, int y)
{
Console.WriteLine("Execute Constructor ProtoType()");
this.x = x;
this.y = y;
}
public ProtoType Clone()
{
Console.WriteLine("Execute ProtoType.Clone()");
return (ProtoType)this.MemberwiseClone();
}
}
Because x, y and list are not variables in this scope. they are members of the class ProtoType. you need to watch for p.x, p.y and p.list in place of the x, y, list.

Union of delegates [duplicate]

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;
}

Overloading methods for different geomethrical figures areas

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();
}

C# delegate only writes out last method

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;
}

Why am I getting these out parameter errors in C#?

I am new to C#. I've tried this with out parameter in C#
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
class First
{
public void fun(out int m)
{
m *= 10;
Console.WriteLine("value of m = " + m);
}
}
class Program
{
static void Main(string[] args)
{
First f = new First();
int x = 30;
f.fun(out x);
}
}
but i get some errors like "Use of unassigned out parameter 'm'" and
The out parameter 'm' must be assigned to before control leaves the current method.
So what is the meaning of these errors and why it is compulsory to assign 'm' when i'm already assigned a value to x.
ref means that you are passing a reference to a variable that has been declared and initialized, before calling the method, and that the method can modify the value of that variable.
out means you are passing a reference to a variable that has been declared but not yet initialized, before calling the method, and that the method must initialize or set it's value before returning.
You're getting an error because a variable sent to a method as an out parameter does not have to be initialized before the method call. The following is 100% correct code:
class Program
{
static void Main(string[] args)
{
First f = new First();
int x;
f.fun(out x);
}
}
Looks like you're looking for ref instead of out here:
class First
{
public void fun(ref int m)
{
m *= 10;
Console.WriteLine("value of m = " + m);
}
}
class Program
{
static void Main(string[] args)
{
First f = new First();
int x = 30;
f.fun(ref x);
}
}
out parameters are for when the function wants to pass a value out of itself. What you want here is ref, which is when the function expects it to be passed in, but can change it.
For examples of how both are supposed to be used, read http://www.dotnetperls.com/parameter. It's explained in simple terms, and you should be able to get a good understanding of it.
You should note that in your code, you never access the variable after the function call, therefore ref doesn't actually do anything. Its purpose is to send changes back to the original variable.
As of C# 7.0 the ability to declare a variable right at the point where it is passed as an out argument was introduced.
Before:
public void PrintCoordinates(Point p)
{
int x, y; // have to "predeclare"
p.GetCoordinates(out x, out y);
WriteLine($"({x}, {y})");
}
C# 7.0
public void PrintCoordinates(Point p)
{
p.GetCoordinates(out int x, out int y);
WriteLine($"({x}, {y})");
}
You can even use var key word:
p.GetCoordinates(out var x, out var y);
Be carefull with the scope of out parameter. For example, in the following code, "i" is only used within if-statement:
public void PrintStars(string s)
{
if (int.TryParse(s, out var i)) { WriteLine(new string('*', i)); }
else { WriteLine("Cloudy - no stars tonight!"); }
}
Further information can be found here. This link is not only about out parameter, but all the new features introduced in c# 7.0
public void Ref_Test(ref int x)
{
var y = x; // ok
x = 10;
}
// x is treated as an unitialized variable
public void Out_Test(out int x)
{
var y = x; // not ok (will not compile)
}
public void Out_Test2(out int x)
{
x = 10;
var y = x; // ok because x is initialized in the line above
}

Categories

Resources