With the use of delegates, I want number 5 from IEnumerable items to print to the screen by using the following code;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using extended;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
IEnumerable<int> cities = new[] { 1, 2, 3, 4, 5 };
IEnumerable<int> query = cities.StartsWith(hello);
foreach (var item in query)
{
Console.WriteLine(item);
}
Console.ReadKey();
}
static int hello(int x)
{
return x > 4 ? x : 0;
}
}
}
namespace extended
{
public static class A
{
public static IEnumerable<T> StartsWith<T>(this IEnumerable<T> input, inputdelegate<T> predicate)
{
foreach (var item in input)
{
if (item.Equals(predicate))
{
yield return item;
}
}
}
public delegate int inputdelegate<T>(T input);
}
}
code compiles without any error but displays no output to the screen. Any idea where I might be going wrong?
You are not invoking your predicate. Also, inputdelegate should probably have a return type of T. Change your code to this:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using extended;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
IEnumerable<int> cities = new[] { 1, 2, 3, 4, 5 };
IEnumerable<int> query = cities.StartsWith(hello);
foreach (var item in query)
{
Console.WriteLine(item);
}
Console.ReadKey();
}
static int hello(int x)
{
return x > 4 ? x : 0;
}
}
}
namespace extended
{
public static class A
{
public static IEnumerable<T> StartsWith<T>(this IEnumerable<T> input, inputdelegate<T> predicate)
{
foreach (var item in input)
{
if (item.Equals(predicate(item)))
{
yield return item;
}
}
}
public delegate T inputdelegate<T>(T input);
}
}
UPDATE: Based on comments from AlexD, you should consider changing your test to:
if (predicate(item))
and updating your delegate to:
public delegate bool inputdelegate<T>(T input);
and updating your Hello function to:
static bool hello(int x)
{
return x > 4;
}
Related
using System;
namespace zestaw_6
{
public class Program
{
public static void Main(string[] args)
{
var zoo = new Zoo();
zoo.Add(new Opiekun("Jan", "Kowalski"));
Console.ReadKey();
}
}
using System;
using System.Collections.Generic;
using System.Text;
using System.Linq;
namespace zestaw_6
{
public static class ActionExtensions
{
public static IList<TObj> Set<TObj, TAg>(this TAg aggregatedObj) where TObj : IInfo where TAg : IAction
{
var aggregatedObjType = aggregatedObj.GetType();
var propertyInfo = aggregatedObjType.GetProperties().FirstOrDefault(p => p.PropertyType == typeof(IList<TObj>));
var propertyValue = propertyInfo?.GetValue(aggregatedObj);
return propertyValue as IList<TObj>;
}
public static C Get<C>(this IAction container, Func<C, bool> searchPredicate = null) where C : IInfo
{
return searchPredicate == null ? container.Set<C, IAction>().FirstOrDefault() : container.Set<C, IAction>().FirstOrDefault(searchPredicate);
}
public static IList<C> GetList<C>(this IAction container, Func<C, bool> searchPredicate = null) where C : IInfo
{
return searchPredicate == null ? container.Set<C, IAction>() : container.Set<C, IAction>().Where(searchPredicate).ToList();
}
public static S Add<C, S>(this S container, C element) where S : IAction where C : IInfo
{
container.Set<C, IAction>().Add(element);
return container;
}
public static C Remove<C>(this IAction container, Func<C, bool> searchFn) where C : IInfo
{
var obj = container.Set<C, IAction>().SingleOrDefault(searchFn);
if(obj != null)
{
container.Set<C, IAction>().Remove(obj);
}
return obj;
}
public static C AddInto<C>(this C obj, IAction container) where C : IInfo
{
container.Set<C, IAction>().Add(obj);
return obj;
}
public static void ForEach<T>(this IList<T> list, Action<T> action) where T : IInfo
{
for(int i = 0; i < list.Count; i++)
{
action(list[i]);
}
}
}
}
using System;
using System.Collections.Generic;
using System.Text;
namespace zestaw_6
{
public class Zoo : IInfo, IAction
{
public List<Klatka> klatki = new List<Klatka>();
public List<Opiekun> opiekunowie = new List<Opiekun>();
public void DisplayInfo()
{
foreach (var item in klatki)
{
item.DisplayInfo();
}
foreach (var item in opiekunowie)
{
item.DisplayInfo();
}
}
}
}
using System;
using System.Collections.Generic;
using System.Text;
namespace zestaw_6
{
public class Opiekun : IInfo, IAction
{
public List<Klatka> klatki = new List<Klatka>();
public string imie { get; set; }
public string nazwisko { get; set; }
public Opiekun(string imie_, string nazwisko_)
{
imie = imie_;
nazwisko = nazwisko_;
}
public void DisplayInfo()
{
Console.WriteLine("Imie: {0}", imie);
Console.WriteLine("Nazwisko: {0}", nazwisko);
foreach (var item in klatki)
{
item.DisplayInfo();
}
}
}
}
Basically, program gives expection "System.NullReferenceException: „Object reference not set to an instance of an object.” at Add function container.Set<C, IAction>().Add(element);. container.Set<C, IAction>() returns null and i dont know why. Funcion Add in main should Add new object to list "opiekunowie" in class zoo. What is the reason for that to not work?
Your code uses reflection, but doesn't find what it wants, for two reasons.
The reflection is done here:
public static IList<TObj> Set<TObj, TAg>(this TAg aggregatedObj) where TObj : IInfo where TAg : IAction
{
var aggregatedObjType = aggregatedObj.GetType();
var propertyInfo = aggregatedObjType.GetProperties().FirstOrDefault(p => p.PropertyType == typeof(IList<TObj>));
var propertyValue = propertyInfo?.GetValue(aggregatedObj);
return propertyValue as IList<TObj>;
}
It looks for properties of type IList<something> (this is reason 1).
You inside Zoo have:
public List<Klatka> klatki = new List<Klatka>();
public List<Opiekun> opiekunowie = new List<Opiekun>();
fields of type List<something>
So correct like this (to have properties):
public List<Klatka> klatki { get; set; } = new List<Klatka>();
public List<Opiekun> opiekunowie { get; set; } = new List<Opiekun>();
and then (to check for properties of a type assignable to IList<something> (this is reason 2)
var propertyInfo = aggregatedObjType.GetProperties().FirstOrDefault(p => typeof(IList<TObj>).IsAssignableFrom(p.PropertyType));
using System;
using System.Collections.Generic;
using System.Linq;
class Program
{
static void Main()
{
List<A> l = new List<A>();
l.Add(new A("q"));
l.Union(new[] {new A("w"), new A("E")}, new AComparer());
Console.Write(l.Count);
}
}
public class A
{
public String b;
public A(String x)
{
b = x;
}
}
public class AComparer : IEqualityComparer<A>
{
public bool Equals(A x, A y)
{
return x != null && y != null && x.b.Equals(y.b);
}
public int GetHashCode(A obj)
{
return 0;
}
}
Unable to figure out how to make the list size go 3? I tried looking up https://msdn.microsoft.com/en-us/library/bb341731(v=vs.110).aspx but unable to figure out if I'm missing anything
Union isn't a member of list, but is an extension on IEnumerable - part of Linq. This means it's pure and doesn't affect the state of the list, but returns a new Enumeration. So you could do
l = l.Union(otherL).ToList();
I'm looking for a more lazy/IEnumerable/cleaner way of doing the following. I particularly not happy with the use of helper and Aggregate.
Any hints on how to modify the code to make it possible?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Test1
{
class Program
{
static void PrintOut<T>(IEnumerable<IEnumerable<T>> data)
{
foreach (var item in data)
{
string output = "-";
if (item != null)
output = string.Join(",", item.Select(x => (x == null) ? "-" : x.ToString()));
Console.WriteLine(output);
}
}
static IEnumerable<T> helper<T>(IEnumerable<T> orig, T toAdd)
{
if (orig != null)
foreach (var item in orig)
yield return item;
yield return toAdd;
yield break;
}
static IEnumerable<IEnumerable<T>> helper2<T>(IEnumerable<IEnumerable<T>> input) where T : class
{
var initalAcc = new List<IEnumerable<T>> { };
var result = input.Aggregate(initalAcc,
(acc, choiceSet) =>
acc.DefaultIfEmpty()
.SelectMany((chosen) => (choiceSet ?? new List<T> { }).DefaultIfEmpty().Select(choice => helper(chosen, choice))).ToList()
);
return result;
}
static void Main(string[] args)
{
var preCombination = new List<List<string>> {
new List<string> {"1","2"},
new List<string> {"3"},
new List<string> {"4","5"},
null,
new List<string> {"6","7"}
};
var postCombination = helper2(preCombination);
PrintOut(preCombination);
Console.WriteLine();
PrintOut(postCombination);
Console.ReadLine();
}
}
}
Here is the expected output
1,2
3
4,5
-
6,7
1,3,4,-,6
1,3,4,-,7
1,3,5,-,6
1,3,5,-,7
2,3,4,-,6
2,3,4,-,7
2,3,5,-,6
2,3,5,-,7
I've changed initalAcc now
var initalAcc = Enumerable.Empty<IEnumerable<T>>();
Here you go. ConcatItem and Yield replace helper.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Test1
{
class Program
{
static void PrintOut<T>(IEnumerable<IEnumerable<T>> data)
{
foreach (var item in data)
{
string output = "-";
if (item != null)
output = string.Join(",", item.Select(x => (x == null) ? "-" : x.ToString()));
Console.WriteLine(output);
}
}
static IEnumerable<T> Yield<T>(T item)
{
yield return item;
}
static IEnumerable<T> ConcatItem<T>(IEnumerable<T> enumerable, T item)
{
return enumerable == null ? Yield(item) : enumerable.Concat(Yield(item));
}
static IEnumerable<IEnumerable<T>> helper2<T>(IEnumerable<IEnumerable<T>> input) where T : class
{
var initalAcc = Enumerable.Empty<IEnumerable<T>>();
var result = input.Aggregate(initalAcc,
(acc, choiceSet) =>
acc.DefaultIfEmpty()
.SelectMany((chosen) => (choiceSet ?? Enumerable.Empty<T>()).DefaultIfEmpty().Select(choice => ConcatItem(chosen, choice)))
);
return result;
}
static void Main(string[] args)
{
var preCombination = new List<List<string>> {
new List<string> {"1","2"},
new List<string> {"3"},
new List<string> {"4","5"},
null,
new List<string> {"6","7"},
};
var postCombination = helper2(preCombination);
PrintOut(preCombination);
Console.WriteLine();
PrintOut(postCombination);
Console.ReadLine();
}
}
}
There is the command hierarchy in my current application.
public interface ICommand
{
void Execute();
}
So, some commands are stateful, some are not.
I need to enumerate IEnumerable in the circular way for some command implementation during command execution.
public class GetNumberCommand : ICommand
{
public GetNumberCommand()
{
List<int> numbers = new List<int>
{
1, 2, 3
};
}
public void Execute()
{
// Circular iteration here.
// 1 => 2 => 3 => 1 => 2 => 3 => ...
}
public void Stop()
{
// Log current value. (2 for example)
}
}
Execute is called from time to time, so it is necessary to store the iteration state.
How to implement that circular enumeration?
I have found two solutions:
Using the IEnumerator<T> interface.
It looks like:
if (!_enumerator.MoveNext())
{
_enumerator.Reset();
_enumerator.MoveNext();
}
Using the circular IEnumerable<T> (yield forever the same sequence): “Implementing A Circular Iterator” - HonestIllusion.Com.
Maybe, there are more ways to achieve it.
What would you recommend to use and why?
Instead of dealing with IEnumerator interface,
foreach (var x in GetSomething())
{
if (someCondition) break;
}
public IEnumerable<int> GetSomething()
{
List<int> list = new List<int>() { 1, 2, 3 };
int index=0;
while (true)
yield return list[index++ % list.Count];
}
Here's one I just implemented as an extension.
using System.Collections;
using System.Collections.Generic;
using System.Linq;
namespace DroopyExtensions
{
public static class CircularEnumaratorExtensionMethod
{
public static IEnumerator<T> GetCircularEnumerator<T>(this IEnumerable<T> t)
{
return new CircularEnumarator<T>(t.GetEnumerator());
}
private class CircularEnumarator<T> : IEnumerator<T>
{
private readonly IEnumerator _wrapedEnumerator;
public CircularEnumarator(IEnumerator wrapedEnumerator)
{
this._wrapedEnumerator = wrapedEnumerator;
}
public object Current => _wrapedEnumerator.Current;
T IEnumerator<T>.Current => (T)Current;
public void Dispose()
{
}
public bool MoveNext()
{
if (!_wrapedEnumerator.MoveNext())
{
_wrapedEnumerator.Reset();
return _wrapedEnumerator.MoveNext();
}
return true;
}
public void Reset()
{
_wrapedEnumerator.Reset();
}
}
}
}
To use it, all you have to do is
using DroopyExtensions;
class Program
{
static void Main(string[] args)
{
var data = new List<string>() {"One", "Two", "Tree"};
var dataEnumerator = data.GetCircularEnumerator();
while(dataEnumerator.MoveNext())
{
Console.WriteLine(dataEnumerator.Current);
}
}
}
You can use this extension method:
public static IEnumerable<T> Cyclic<T>(this IEnumerable<T> #this)
{
while (true)
foreach (var x in #this)
yield return x;
}
In that way:
public class GetNumberCommand : ICommand
{
private readonly IEnumerator<int> _commandState = new[] { 1, 2, 3 }.Cyclic().GetEnumerator();
public void Execute()
{
_commandState.MoveNext();
var state = _commandState.Current;
//
// Do stuff with state
//
}
public void Stop()
{
var state = _commandState.Current;
// Log state value. (2 for example)
}
}
while (!stop)
{
foreach (var i in numbers)
{
// do something
}
}
I think, the most comfortable way wil be to implement custom collection with custom enumerator and encapsulate circular logic in it.
class Collection<T> : IEnumerable<T>
{
bool circle;
List<T> collection = new List<T>();
public IEnumerable<T> IEnumerable<T>.GetEnumerator()
{
if(circle) return new CustomEnumerator<T>(this);
return circle.GetEnumerator();
}
}
class CustomEnumerator : Enumerator<T> {}
something like this...
You can write a circular enumerable without yield returns.
public class CircularEnumerable<T> : IEnumerable<T>
{
public CircularEnumerable (IEnumerable<T> sequence)
{
InfiniteLoop = sequence.Concat (this);
}
private readonly IEnumerable<T> InfiniteLoop;
public IEnumerator<T> GetEnumerator ()
{
return InfiniteLoop.GetEnumerator ();
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator ()
{
return InfiniteLoop.GetEnumerator ();
}
}
public class GetNumberCommand : ICommand
{
public GetNumberCommand()
{
List<int> numbers = new List<int>
{
1, 2, 3
};
infiniteLoopOnNumbers = new CircularEnumerable<int>(numbers).GetEnumerator();
}
IEnumerator<int> infiniteLoopOnNumbers;
public void Execute()
{
infiniteLoopOnNumbers.MoveNext();
}
public void Stop()
{
int value = infiniteLoopOnNumbers.Current;
}
}
I have a class that creates a static array of all properties, using a static constructor. I also have a function -- GetNamesAndTypes() -- that lists the name & type of each property in that array.
Now I want to create another instance-level function -- GetNamesAndTypesAndValues() -- that displays the name & type of each property in the class, as well as that instance's value. How would I do that? Here's the code that I've written so far:
//StaticTest.cs
using System;
using System.ComponentModel;
using System.Globalization;
using System.Reflection;
namespace StaticTest
{
public class ClassTest
{
private string m_A, m_B, m_C;
private static PropertyInfo[] allClassProperties;
static ClassTest()
{
Type type = typeof(ClassTest);
allClassProperties = type.GetProperties();
// Sort properties alphabetically by name
// (http://www.csharp-examples.net/reflection-property-names/)
Array.Sort(allClassProperties, delegate(PropertyInfo p1, PropertyInfo p2)
{
return p1.Name.CompareTo(p2.Name);
});
}
public int A
{
get { return Convert.ToInt32(m_A); }
set { m_A = value.ToString(); }
}
public string B
{
get { return m_B; }
set { m_B = value; }
}
public DateTime C
{
get { return DateTime.ParseExact("yyyyMMdd", m_C,
CultureInfo.InvariantCulture); }
set { m_C = String.Format("{0:yyyyMMdd}", value); }
}
public static void GetNamesAndTypes()
{
foreach (PropertyInfo propertyInfo in allClassProperties)
{
Console.WriteLine("{0} [type = {1}]", propertyInfo.Name,
propertyInfo.PropertyType);
}
}
public void GetNamesAndTypesAndValues()
{
foreach (PropertyInfo propertyInfo in allClassProperties)
{
Console.WriteLine("{0} [type = {1}]", propertyInfo.Name,
propertyInfo.PropertyType);
}
}
}
}
//Program.cs
using System;
using System.Collections.Generic;
using StaticTest;
namespace ConsoleApplication2
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("[static] GetNamesAndTypes()");
ClassTest.GetNamesAndTypes();
Console.WriteLine("");
ClassTest classTest = new ClassTest();
classTest.A = 4;
classTest.B = #"bacon";
classTest.C = DateTime.Now;
Console.WriteLine("[instance] GetNamesAndTypesAndValues()");
classTest.GetNamesAndTypesAndValues();
Console.ReadLine();
}
}
}
I tried using propertyInfo.GetValue(), but I couldn't get it to work.
In your example propertyInfo.GetValue(this, null) should work. Consider altering GetNamesAndTypesAndValues() as follows:
public void GetNamesAndTypesAndValues()
{
foreach (PropertyInfo propertyInfo in allClassProperties)
{
Console.WriteLine("{0} [type = {1}] [value = {2}]",
propertyInfo.Name,
propertyInfo.PropertyType,
propertyInfo.GetValue(this, null));
}
}