I have this an implementation of class IntList. I'm am supposed to: Use the capability of the anonymous methods to refer to a local variable in their enclosing method and the defined "Act"-method to compute the sum of an IntList’s elements (without writing any loops yourself). This is what I have done so far, but I doubt that it is correct. Any suggestions and explanations will help me here
What is my anonymous method's enclosing method in this case?
public delegate bool IntPredicate(int x);
public delegate void IntAction(int x);
class IntList : List<int>
{
public IntList(params int[] elements) : base(elements)
{
}
public void Act(IntAction f)
{
foreach(int i in this)
{
f(i);
}
}
public IntList Filter(IntPredicate p)
{
IntList res = new IntList();
foreach (int i in this)
{
if (p(i))
{
res.Add(i);
}
}
return res;
}
}
class Program
{
static void Main(string[] args)
{
// code here
IntList xs = new IntList();
// adding numbers, could be random. whatever really. Here just 0..29
for(int i =0; i<30; i++)
{
xs.Add(i);
}
int total = 0;
xs.Act(delegate (int x)
{
total = total + x;
Console.WriteLine(total);
}
);
Console.ReadKey();
}
}
I think this part is the "anonymous method" (because it is defined inline and doesn't have a method name):
delegate (int x)
{
total = total + x;
Console.WriteLine(total);
}
I think the "enclosing method" is Main().
I think the "local variable" is most likely total.
I ran your code and it seems correct to me.
Related
I do understand how both interfaces (IEnumerator and IEnumerable) work and what they are used for. However, I never quite understood when to create a class that is derived from one of these two interfaces. You can do a foreach loop on a list, on an array, and other generic collections as far as I am aware without having to create a class like I did in my code:
class Program
{
public static int[] array = new int[3] { 1, 2, 3 };
static void Main(string[] args)
{
var Enumerable = new Aninfiniteenumerator();
foreach(var i in infiniteEnumerable)
{
Console.WriteLine($"I is {i}");
}
Console.ReadKey();
}
}
class Aninfiniteenumerator : IEnumerable<int> //Creating a class that is derived from IEnumerable
{
public IEnumerator GetEnumerator()
{
return new MyInfiniteEnumer(Program.array);
}
IEnumerator<int> IEnumerable<int>.GetEnumerator()
{
return new MyInfiniteEnumer(Program.array);
}
}
public class MyInfiniteEnumer : IEnumerator<int> ////Creating a class that is derived from IEnumerator
{
private int[] values;
private int index = -1;
public int Current => values[index];
object IEnumerator.Current => Current;
public MyInfiniteEnumer (int [] values)
{
this.values = values;
}
public void Dispose()
{
}
public bool MoveNext()
{
index++;
return index < values.Length;
}
public void Reset()
{
}
}
PS. I know that my enumerators are called "infinite enumerators" yet they are not infinite. So, as I have said, it is possible to do a foreach loop over a generic list/an array without having to create an IEnumerable/IEnumerator classes:
class Program
{
static void Main(string[] args)
{
Random rand = new Random();
List<Car> vehicles = new List<Car>();
for(int i = 0; i < 100; i++)
{
vehicles.Add(new Car(rand.Next(1970,2021), "Honda"));
}
foreach(var car in vehicles)
{
Console.WriteLine(car.yearProduced + ", " + car.model);
}
Console.ReadKey();
for (int i = 0; i < 100; i++)
{
vehicles.Add(new Car(rand.Next(1970, 2021), "Subaru"));
}
foreach (var car in vehicles)
{
Console.WriteLine(car.yearProduced + ", " + car.model);
}
Console.WriteLine(vehicles.Count());
Console.ReadKey();
}
}
class Car
{
public string model { get; set; }
public int yearProduced { get; set; }
public Car (int year, string model)
{
yearProduced = year;
this.model = model;
}
}
Back to my question, I wrote the first code to be able to do a foreach loop over the var called "Enumerable". I only wrote this code for practice and see no practical use of creating classes that are derived from IEnumerable and IEnumerator. So, my question is, what are some situations where you'd have to create a class that is derived from one of these two interfaces?
A good example of a custom structure that could use the enumerator is the binary tree.
A simplest tree would be
public class Tree
{
public Tree Left { get; set; }
public Tree Right { get; set; }
public object Value { get; set; }
}
This definition can be used to compose arbitrary trees:
var root = new Tree()
{
Left = new Tree() { Value = 1 },
Right = new Tree() { Value = 2 },
Value = 3
}
Note that my tree is balanced but actual trees don't have to be.
Now, how are you supposed to enumerate all values? It's not that easy, in each node you have to decide whether or not it has subnodes and when you are done at the node, you have to go back to its parent and explore all paths.
But the client code is not interested in whether or not it's difficult, it expects the code to be
foreach ( var val in root )
{
// I want all values from the tree here!
}
This is when the idea of enumeration starts to make sense. It's not only about simple, linear structures, like arrays or lists!
public class Tree : IEnumerable
{
public IEnumerator GetEnumerator()
{
if ( Left != null ) foreach ( var e in Left ) yield return e;
if ( Right != null ) foreach ( var e in Right ) yield return e;
yield return Value;
}
}
I hope this example sheds some lights on the issue.
This is the Question I am trying to solve in C Sharp.
I am getting an error:
Error Expected ; or = (cannot specify constructor arguments in declaration)
Can anyone help me to solve this or guide me to solve this?
namespace program
{
public class Integer
{
private int intvar;
public Integer()
{
intvar = 0;
}
public Integer(int x)
{
intvar = x;
}
public void display()
{
Console.Write(intvar);
Console.Write("\n");
}
public void add(Integer x, Integer y)
{
intvar = x.intvar + y.intvar;
}
}
class Program
{
static void Main(string[] args)
{
Integer a(5),b(45);
Integer c;
c.add(a,b);
c.display();
Console.ReadLine();
}
}
}
You cannot create objects like that in C#. Im assuming you come from C++ where this syntax is possible.
In C# you have to create objects using new:
Integer foo = new Integer(45);
To create a new instance of a type, you have to invoke one of the constructors of that type using the new operator. For example:
class Program
{
static void Main(string[] args)
{
var a = new Integer(5);
var b = new Integer(45);
var c = new Integer(); //result instance
c.add(a, b);
c.display();
Console.ReadLine();
}
}
I'm having trouble creating an extension method on an ObservableCollection for a custom type. The extension method I need to create is the "ToAnotherType" kind (as in, ToList, ToArray). The MyPoint example implements the IEnumerable interface, but I think I am not exposing the yield correctly?
The real thing obviously has more stuff going on, this is just a stripped down sample in a console app to identify the issue. I've tried changing the OC to a regular List to see if something was going on there, but it's not.
I see many of the "How to make your class Enumerable" examples create a second class derived from List (IE, public class MyPointList : List) but that seems wasteful when the original type can handle it itself, or have it pushed off in a partial class file.
It all looks like it's working until the foreach in the extension method itself- Where I get an error saying 'MyPoint' does not contain a definition for 'X' and 'Y'.
I could obviously handle the conversion with a method that takes in a List and returns a List, but it would be really nice to have the extension.
references as to how I ended up with code I did:
https://www.codeproject.com/Articles/474678/A-Beginners-Tutorial-on-Implementing-IEnumerable-I
https://dotnetcodr.com/2015/07/24/implementing-an-enumerator-for-a-custom-object-in-net-c/
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Drawing;
using System.Collections;
namespace EnumerableDemo
{
class Program
{
static void Main(string[] args)
{
var myPoints = new ObservableCollection<MyPoint>
{
new MyPoint(10, 10),
new MyPoint(20, 20),
new MyPoint(30, 30),
new MyPoint(40, 40),
new MyPoint(50, 50)
};
Console.WriteLine("Print a single point via extension method:");
PrintSinglePointToConsole(myPoints[0].ToPoint());
Console.WriteLine("");
Console.WriteLine("Print the whole OC of points:");
PrintPointsToConsole(myPoints.ToPoints());
Console.ReadLine();
}
public static void PrintSinglePointToConsole(Point point)
{
Console.WriteLine("Point {0},{1}", point.X, point.Y);
}
public static void PrintPointsToConsole(List<Point> points)
{
foreach (var item in points)
{
Console.WriteLine("Point: {0},{1}", item.X, item.Y);
}
}
}
public class MyPoint : IEnumerable<MyPoint>
{
private List<MyPoint> _myPoints = new List<MyPoint>();
private int _x { get; set; } = 0;
public int X { get { return _x; } set { _x = value; } }
private int _y { get; set; } = 0;
public int Y { get { return _y; } set { _y = value; } }
public MyPoint()
{
}
public MyPoint(int x, int y)
{
_x = x;
_y = y;
}
public IEnumerator<MyPoint> GetEnumerator()
{
foreach (var item in _myPoints)
{
yield return item;
}
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
public static class MyPointExtension
{
public static Point ToPoint(this MyPoint point)
{
return new Point(point.X, point.Y);
}
public static List<Point> ToPoints<MyPoint>(this ObservableCollection<MyPoint> list)
{
var result = new List<Point>();
foreach (var item in list)
{
//Line with error:
//'MyPoint' Does not contain a definition for 'X' and no extension method for
//'X' accepting a first argument type of 'MyPoint' could be found.
result.Add(new Point(item.X, item.Y));
}
return result;
}
}
}
You don't need a MyPoint generic parameter in ToPoints.
Just use
public static List<Point> ToPoints(this ObservableCollection<MyPoint> list)
And the result is:
Print a single point via extension method:
Point 10,10
Print the whole OC of points:
Point: 10,10
Point: 20,20
Point: 30,30
Point: 40,40
Point: 50,50
BTW, you can also make a code a bit cleaner and shorter if you discard the _x and _y fields, like this:
public int X { get; set; } = 0;
public int Y { get; set; } = 0;
public MyPoint(int x, int y)
{
X = x;
Y = y;
}
Final code block, which makes use of the other extension method ToPoint
public static List<Point> ToPoints(this ObservableCollection<MyPoint> list)
{
var result = new List<Point>();
foreach (var item in list)
{
result.Add(item.ToPoint());
}
return result;
}
In C I can do
void foo() {
static int c = 0;
printf("%d,", c);
c ++;
}
foo();
foo();
foo();
foo();
it should print 0,1,2,3
Is there an equivalent in C#?
While some have suggested as static member variable, this is not the same due to visibility. As an alternative to the answer by aquinas, if closures are accepted, then this can be done:
(Note that Foo is a a property and not a method and that c is "per instance".)
class F {
public readonly Action Foo;
public F () {
int c = 0; // closured
Foo = () => {
Console.WriteLine(c);
c++;
};
}
}
var f = new F();
f.Foo(); // 0
f.Foo(); // 1
However, C# has no direct equivalent to a static variable in C.
Happy coding.
Something like:
class C
{
private static int c = 0;
public void foo()
{
Console.WriteLine(c);
c++;
}
}
No there is no way to achieve the same behaviour as the static c function variable ...
There are no globals in C#, however, you can create a static field within your class.
public class Foo{
private static int c = 0;
void Bar(){
Console.WriteLine(c++);
}
}
You can't do it at a method level. The closest you can do at a method level is something like this, and this isn't really that close. In particular, it only works if you have a reference to the enumerator. If someone else calls this method, they won't see your changes.
class Program {
static IEnumerable<int> Foo() {
int c = 0;
while (true) {
c++;
yield return c;
}
}
static void Main(string[] args) {
var x = Foo().GetEnumerator();
Console.WriteLine(x.Current); //0
x.MoveNext();
Console.WriteLine(x.Current); //1
x.MoveNext();
Console.WriteLine(x.Current); //2
Console.ReadLine();
}
}
What interesting is that VB.NET does support static local variables: http://weblogs.asp.net/psteele/pages/7717.aspx. As this page notes, .NET itself doesn't support this, but the VB.NET compiler fakes it by adding a static class level variable.
How do i get property name of the executing property. If the property uses "return" then
MethodBase.GetCurrentMethod().Name returns the name of the property. But when I use "yield return" MethodBase.GetCurrentMethod().Name returns "MoveNext". how do I get the executing property name when it uses yield return?
Sample Code
class Program
{
static void Main(string[] args)
{
var x = myProgram.Something;
Console.ReadLine();
}
}
public class myProgram
{
public static IEnumerable<string> Something
{
get
{
string var = MethodBase.GetCurrentMethod().Name;
for (int i = 0; i < 5; i++)
{
yield return var;
}
}
}
}
As you've probably noticed, the compiler reorganizes how the methods work and Something returns a private class that implements IEnumerable. As such, the actual contents of your method appear in the MoveNext method of this private class, so MethodBase.GetCurrentMethod doesn't return what it seems like it should return.
It happens that the name of the private class is derived from the original method name, which in this case is <Enumerate>d__0. So, you can parse the original method name from a stack frame.
static IEnumerable<string> Enumerate()
{
var method = new StackTrace(true).GetFrame(0).GetMethod().DeclaringType.Name;
yield return Regex.Replace(method, #".*<([^)]+)>.*", "$1");
}
static void Main(string[] args)
{
foreach (var #string in Enumerate())
{
Console.WriteLine(#string);
}
}
This is, of course, a hack and could easily not work in future versions of .NET
As you can probably guess, the problem here is that a yield return statement does a bit of rewriting behind the scenes, similar to how a using or lambda expression does. It actually gets implemented as an enumerator, with the code that calls yield return being part of the MoveNext method on the enumerator.
This is an overall problem of using Reflection: it gives you runtime information about your executing code, which may not match your compile-time idea of what that code was.
That's a long-winded way of saying that there's no easy way to get the information you want. If you were to move the yield return next into a separate method, then any code outside of that method would not be part of the MoveNext, but that may or may not accomplish what you need. You are no longer actually getting the name of the method that is executing the yield return, you are getting the name of it's caller. If that's all you care about, it looks like this:
public IEnumerable<string> Something
{
get
{
var x = MethodBase.GetCurrentMethod().Name;
return this.DoSomething(x);
}
}
private IEnumerable<string> DoSomething(string x)
{
for (int i = 0; i < 5; i++)
{
yield return x;
}
}
EDIT: While I doubt it will help you in the short term, for the record, this problem is also solved when using C# 5's new attributes. Since the CallerMemberName attribute is resolved at compile time, and apparently before the iterator has been rewritten into an enumerator class, it produces the name of the property:
public IEnumerable<string> Something
{
get
{
var x = this.GetCallerName();
for (int i = 0; i < 5; i++)
{
yield return x;
}
}
}
private string GetCallerName([CallerMemberName] string caller = null)
{
return caller;
}
I would move the iterator into a helper method:
public class myProgram
{
public static IEnumerable<string> Something
{
get
{
string var = MethodBase.GetCurrentMethod().Name;
return GetSomethingInternal();
}
}
private static IEnumerable<string> GetSomethingInternal()
{
for (int i = 0; i < 5; i++)
{
yield return i;
}
}
}