An example for using predicate to replace 'if' in c#? - c#

I read that the 'if' keyword is evil, and better to use predicate to replace if. Then I googled, but still dont get it.
Can anyone be kind to provide an example?

No matter what they say, if is not evil. There may be specific cases for which a Predicate is a better choice than an if (or a set of ifs).
For example,
foreach (Foo f in fooList) {
if (f.Equals(fooTarget)) {
return f;
}
}
versus (.NET 2.0)
fooList.Find(delegate (Foo f) { return f.Equals(fooTarget); });
or (later)
fooList.Find(f => f.Equals(fooTarget));

They are just different. A predicate is more complex than a simple if statement. A predicate is basically a pointer to a method (delegate) which is tied to a type that it takes as a param and returns true/false.
Imagine you are using generics, and like the find method on generic lists, how can it know what types are in the list prior to your initialization of it. So the find method just uses the predicate and does not know how the predicate will be implemented.
public T Find(Predicate<T> p)
{
//iterate through the collection and return the first match
IEnumerator<T> enumerator = this.GetEnumerator();
while (enumerator.MoveNext())
{
if (p(enumerator.Current))
{
return enumerator.Current;
}
}
return default(T);
}
In this case, a predicate is used but what (p(enumerator.Current)) actually evaluates about enumerator.Current is determined during implementation of the predicate. The code is not aware of what type T wil end up being here.
Here are some ways to assign the predicate to a method
Predicate<string> findShortNames1 = x => x.Length == 3; // lambda expression
Predicate<string> findShortNames2 = delegate(string x) { return x.Length == 3; }; // anonymous method
Predicate<string> findShortNames3 = MatchOnShortNames; //existing method
// ...
private bool MatchOnShortNames(string s)
{
return s.Length == 3;
}
Then the usage is like
someList.FindAll(findShortNames1);

For example, whenever you have a loop like this:
List<Employee> retiredEmployees = new List<Employee>();
foreach (Employee employee in EmployeeList)
{
if (employee.IsRetired)
retiredEmployees.Add(employee);
}
Using a predicate, you would have to change it to:
retiredEmployees = EmployeeList.FindAll(e => e.IsRetired);
But I believe, in the whole "if statement considered evil" debate, predicate vs if is just mentioned as a special case of using OOP and functional programming vs procedural programming. This paradigm can be easily generalized to any delegate type (not just predicate), or any use of OOP to replace a conditional:
For example, if you go through your code, you may easily find code such as this:
public class Employee
{
private bool _isRetired;
private double _amount;
public double GetPayAmount()
{
if (_isRetired)
return _amount * 0.9;
else
return _amount;
}
}
Pure OOP supporters will tell you that you immediately need to extract a different type of employee and handle each branch as a different subtype, which will remove the "evil if statement":
public interface IEmployee
{
double GetPayAmount();
}
public class Employee : IEmployee
{
private double _amount;
public double GetPayAmount()
{
return _amount;
}
}
public class RetiredEmployee : IEmployee
{
private double _amount;
public double GetPayAmount()
{
return _amount * 0.9;
}
}
Although the code is easier to maintain this way, the amount of code in the second case has clearly doubled. For a simple hierarchy as this, there is little need to do the refactoring at this phase. If you decide that you need many more special cases, then your conditional might become too complex, and you can easily refactor it later.

I don't use them for straight "if ... else" constructs myself, other than withinn searches, as it also removes the need for loop constructs. For example
int index = this.listObjects.FindIndex(x => x.PropertyA == objectItem.PropertyA);
or
List<ClassA> listClass = new List<ClassA>();
//... some more code filling listClass with ClassA types ...
ClassA tempClassA = listClass.FirstOrDefault().Where(x=> x.PropertyA == someValue);
I must admit though that if there's just a straight comparison to perform on one item then I use and "if ... else" construct.

static void Main()
{
string[] names = { "Lukasz", "Darek", "Milosz" };
foreach (var item in names)
{
if (ContainsL(item))
Console.WriteLine(item);
}
string match1 = Array.Find(names, delegate(string name) { return name.Contains("L"); });
//or
string match2 = Array.Find(names, delegate(string name) { return name.Contains("L"); });
//or
string match3 = Array.Find(names, x => x.Contains("L"));
Console.WriteLine(match1 + " " + match2 + " " + match3); // Lukasz Lukasz Lukasz
}
static bool ContainsL(string name) { return name.Contains("L"); }

Related

Cast IEnumerable interface to concrete type

I have something like:
public interface IThing
{
string Id { get; }
}
public class Ball : IThing
{
public string Id { get; }
}
public class Car : IThing
{
public string Id { get; }
}
For my 3-4 functions I want to treat Ball and Car the same. I use the interface so I dont have to make overload methods (one for car, one for ball).
Finally, there is on function where I have different logic if its a Ball or a Car. I get a IEnumerable<IThings> and I want to cast it to either IEnumerable<Car> or IEnumerable<Ball> depending what it consists of. If it consists of a mix, I want it to fail. It has to be all cars or all balls.
I tried something like:
var things = (inputs is IEnumerable<Ball>) ? input.Locations.Cast<Ball>() : input.Locations.Cast<Car>()
But it doesn't like that. What is the recommended approach where I can have 1 variable?
Edit:
The reason why I wanted to get it into one variable is because I am sending it to an overloaded method. So I want to do this:
var things = (inputs is IEnumerable<Ball>) ? input.Locations.Cast<Ball>() : input.Locations.Cast<Car>()
for (var i = 0; i < numRequests; i++)
{
var thingsSet = things.Skip(i * 1000).Take(1000);
var results = callOverLoadedFunction(thingsSet);
}
Rather than this:
if (inputs is IEnumerable<Ball>)
{
var things = input.Locations.Cast<Ball>();
for (var i = 0; i < numRequests; i++)
{
var thingsSet = things.Skip(i * 1000).Take(1000);
var results = callOverLoadedFunction(thingsSet);
}
}
else
{
var things = input.Locations.Cast<Car>();
for (var i = 0; i < numRequests; i++)
{
var thingsSet = things.Skip(i * 1000).Take(1000);
var results = callOverLoadedFunction(thingsSet);
}
}
The problem in your attempt it this:
inputs is IEnumerable<Ball>
Because an IEnumerable<IThing> that only contains elements of type Ball is not the same type as IEnumerable<Ball>. You really have no choice but to enumerate through your collection to determine if every item matches the type you require. You could use .Cast<...>() and handle the InvalidCastException, but that's a little bit hacky. Another way would be to use OfType<...>:
var cars = inputs.OfType<Car>();
var balls = inputs.OfType<Ball>();
And now you can deal with them as you wish, for example:
if(balls.Any() && cars.Any())
{
//You're not allowed to have balls and cars together
throw new Exception(...);
}
However, you are really breaking the open/closed principle of SOLID here, it seems like you should consider at a higher level what you are trying to achieve.
You could do a convert method, but that would still break some principles, as you still have to place an if statement.
I am not sure, you are using interfaces the right way with what you want to achieve.
If you want a car to behave different from a ball in a specific situation, then the implementation in the car shall do something different than the implementation in the ball.
Do not try to tweak an interface from outside. The implementations have to do this.
Why not create a method DoMySpecialStuff in IThing and you just iterate over your enumerable in this one special method that just calls DoMySpecialStuff on all the elements?
That's the way you can avoid your if-statement.
I just saw your edit with your overloadedMethod
So it could work like this:
for (var i = 0; i < numRequests; i++)
{
var thingsSet = things.Skip(i * 1000).Take(1000);
var results = callOverLoadedFunction(thingsSet);
}
void OverLoadedFunction(IThing thing)
{
thing.DoSpecialStuff(); // This does different things in car/ball
}
You can separate balls and cars from each other using LINQ
IEnumerable<Ball> balls = things.OfType<Ball>();
IEnumerable<Car> cars = things.OfType<Car>();
If you want it to fail and like one line solutions try something like this
IEnumerable<Ball> balls = things.OfType<Ball>().Count() == things.Count() ? things.OfType<Ball>() : null; //or whatever you want
I decided to redo something I did some time ago: the retransformation of partially a enumerated IEnumerator<> to full IEnumerable<>. This solves a problem that I feel is important: you shouldn't enumerate twice "unknown" IEnumerable<> (for "unknown" I mean IEnumerable<> that you haven't built by hand in the same method but that are of unknown origin), because there is no guarantee that it can be done, and even if it can be done, you could cause the big work needed to generate the IEnumerable<> to be done twice.
public class RemainingIEnumerator<T> : IEnumerable<T>
{
public IEnumerable<T> Enumerable { get; set; }
public int Nulls { get; set; }
public T First { get; set; }
public IEnumerator<T> Enumerator { get; set; }
public IEnumerator<T> GetEnumerator()
{
var enumerator = Enumerator;
if (enumerator == null)
{
return Enumerable.GetEnumerator();
}
return GetEnumerableRemaining().GetEnumerator();
}
private IEnumerable<T> GetEnumerableRemaining()
{
var enumerator = Enumerator;
Enumerator = null;
int nulls = Nulls;
Nulls = 0;
T first = First;
First = default(T);
for (int i = 0; i < nulls; i++)
{
yield return default(T);
}
yield return first;
while (enumerator.MoveNext())
{
yield return enumerator.Current;
}
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
public static bool Is<T>(IEnumerable<T> enu, Type type, out IEnumerable<T> enu2)
{
IEnumerator<T> enumerator = null;
int nulls = 0;
try
{
enumerator = enu.GetEnumerator();
while (enumerator.MoveNext())
{
var current = enumerator.Current;
if (current == null)
{
nulls++;
continue;
}
enu2 = new RemainingIEnumerator<T>
{
Enumerable = enu,
Nulls = nulls,
First = current,
Enumerator = enumerator,
};
enumerator = null;
return current.GetType() == type;
}
// Only nulls case
enu2 = new T[nulls];
return false;
}
finally
{
if (enumerator != null)
{
enumerator.Dispose();
}
}
}
The Is<T>() function returns true if the first non-null element is of the type type. It returns a new IEnumerable<> that can be used and that, through "magic", reuses the IEnumerable<> that was passed to Is<> (in some way it restitches the optional initial nulls, the first found element and the unused remaining IEnumerator<>).
Example of use:
var enu1 = new object[] { null, new Dog(), new Cat(), new Dog() };
IEnumerable<object> enu2;
// From this line onward, you should use at least one enu2!
// It is the partially unwinded enu1 that has been rewinded through
// some magic :-)
bool isDog = Is(enu1, typeof(Dog), out enu2);
if (isDog)
{
// Note the use of enu2!
foreach (Dog dog in enu2.Cast<Dog>())
{
}
}
using System;
using System.Collections.Generic;
using System.Linq;
public class Program
{
public static void Main()
{
List<IThing> testCollection = new List<IThing>();
testCollection.Add(new Ball());
testCollection.Add(new Car());
try
{
if (testCollection[0] is Ball)
{
Console.WriteLine(testCollection.Cast<Ball>().Count().ToString());
}
else
{
Console.WriteLine(testCollection.Cast<Car>().Count().ToString());
}
}
catch(InvalidCastException ex)
{
Console.WriteLine("Mix isn't allowed!");
}
}
}
public interface IThing
{
string Id { get; set;}
}
public class Ball : IThing
{
public string Id { get;set; }
}
public class Car : IThing
{
public string Id { get;set; }
}
This code will throw an InvalidCastException at the call to Cast<Ball> as the Car object can't be cast to Ball. This should do what you wanted, if I'm not mistaken.
The code will only check the type of the first element, as the List shouldn't be mixed, it can be assumed that all the other objects in that List should have the same type, if not that's, in my opinion and from how the question was written, appropiate cause to throw an exception.
Remember that IEnumerable<> is covariant, that is, you can substitute IEnumerable<Derived> whenever an IEnumerable<Base> is needed.
If you have only pure containers of things, that is only things of the same kind are in a given container, then you should make that container (which will be passed as an IEnumerable at some point) of that specific type. For example a factory could produce a true list of cars, a List<car>, in code like IEnumerable<Thing> things = factory.produceList(ThingTypes.Car);. Like all types, IEnumerable<> objects retain their actual type information even when they get assigned to references of a more basic type. This type can be used to distinguish the actual type of the IEnumerable<> at run-time.
Perhaps some code is easier to understand. I create two IEnumerable<I>s with elements of two distinct types which both implement the same interface I. As I said, I can assign an IEnumerable<T> to an IEnumerable<I> as long as T implements I.
using System;
using System.Collections.Generic;
namespace ConsoleApplication34
{
interface I { };
class T1 : I { }
class T2 : I { }
class Program
{
// strongly typed arrays get assigned to base type IEnumerables.
static IEnumerable<I> i1 = new T1[] { new T1(), new T1() };
static IEnumerable<I> i2 = new T2[] { new T2(), new T2() };
static void Main(string[] args)
{
// Note: compile-time type of array elements is IEnumerable<I>!
IEnumerable<I>[] iEnumArr = new IEnumerable<I>[] { i1, i2 };
foreach (IEnumerable<I> ie in iEnumArr)
{
// ... but the run-time types of the IEnumerable objects
// are actually different.
Console.WriteLine("ienumerable is of T1: " + (ie is IEnumerable<T1>));
Console.WriteLine("ienumerable is of T2: " + (ie is IEnumerable<T2>));
}
}
}
}
The output is
ienumerable is of T1: True
ienumerable is of T2: False
ienumerable is of T1: False
ienumerable is of T2: True
Edit of the edit: I see that you are working with thingsSet which is a true IEnumerable<Thing>. True, then the type tests don't work any longer.
Edit: Your edit is a bit unclear to me, but I assume that your overloaded method has two (or n) versions, one for an IEnumerable<car> and one for an IEnumerable<ball>. In that case I would do everything which is independent on the concrete type of the Thing first, and then distinguish only for the part where it matters. For example:
for (var i = 0; i < numRequests; i++)
{
var thingsSet = things.Skip(i * 1000).Take(1000);
// I may see your problem: Now with thingsSet we have true
// Enumerables of Thing, and the tests below are always false.
// Hm.
var carSet = thingsSet as IEnumerable<car>;
var ballSet = thingsSet as IEnumerable<ball>;
bool results;
if(carSet != null ) { results = callOverLoadedFunction(carSet); }
else if(ballSet != null) { results = callOverLoadedFunction(ballSet); }
else { throw /*...*/}
}
This solution has a bit of a code smell; ideally the calling code whouldn't be concerned with the concrete type of things. One possibility is to leave the "branching" for the distinct types to the Things. Or if that isn't possible, provide a single callNonOverLoadedFunction(IEnumerable<Thing>) with then branches internally, invisible to the caller. These functions are probably closer to the Things implementation and "know" which different types of Things exist; your calling code does not, and does not want to know, from a maintenance perspective.

multiple generic overloads

I have a simple helper class that I use to build a simple comma separated string.
private string AddcsvString(string s)
{
if(string.IsNullOrWhiteSpace(this.Value))
{
return s;
}
else
{
return this.Value + "," + s;
}
}
I also have a generic method that calls this
public void Add<T>(T s) where T: struct
{
this.Value = AddcsvString(s.ToString());
}
I wanted to add an overload for a generic List
public void Add<T>(IEnumerable<T> values)where T:struct
{
foreach (T t in values)
{
Add(t.ToString());
}
}
But any attempt to call this called the first generic method. So I ended up renaming the second generic method to AddAll. In the end I think this was the right way to go for this case but would like to know if it is possible to have both for future reference.
--edit
Here is the case that doesn't work
CsvString test = new CsvString();
string result;
test.Add(1);
test.Add('2');
test.Add("3");
result = test.ToString(); // result = "1,2,3"
CsvString test2 = new CsvString();
List<long> aList = new List<long>();
string result2;
aList.Add(1);
aList.Add(2);
aList.Add(3);
test2.Add(aList); //line doesn't compile
--edit 2
I found a second solution (though JoshE below gets credit for answering this, thanks btw).
I changed the second method to this
public SWcsvString Add<T,K>(T values)where T: IEnumerable<K> where K: struct
{
foreach (K k in values)
{
Add(k.ToString());
}
return this;
}
and the call to this
test2.Add<IEnumerable<long>,long>(aList);
Try removing your constraints where T : struct, and I think you will get the proper behavior.
IEnumerable<char> <==> String, since a string is just a char[]. Since a string is not really a value-object, overload resolution will almost always favor the first method to avoid the boxing/unboxing operation of converting a string to IEnumerable<char>. (I'm guessing that you've tried calling it with both "foo" and IEnumerable<bar> where bar is a struct).

Complexity between IEnumerable<T> return type implementation

Is there a significant complexity difference between these two implementation or does the compiler optimize it anyway?
Usage:
for(int i = 0; i < int.MaxValue; i++)
{
foreach(var item in GoodItems)
{
if(DoSomethingBad(item))
break; // this is later added.
}
}
Implementation (1):
public IEnumerable<T> GoodItems
{
get { return _list.Where(x => x.IsGood); }
}
Implementation (2):
public IEnumerable<T> GoodItems
{
get { foreach(var item in _list.Where(x => x.IsGood)) yield return item; }
}
It appears that IEnumerable methods should always be implemented using (2)? When is one better than the other?
I just built an example program and then used ILSpy to examine the output assembly. The second option will actually generate an extra class that wraps the call to Where but adds zero value to the code. The extra layer the code must follow will probably not cause performance issues in most programs but consider all the extra syntax just to perform the same thing at a slightly slower speed. Not worth it in my book.
where uses yield return internally. You don't need to wrap it in another yield return.
You do _list.where(x => x.IsGood); in both. With that said, isn't it obvious which has to be the better usage?
yield return has its usages, but this scenario, especially in a getter, is not the one
The extra code without payload in "implementation 2" is the less evil here.
Both variants lead to undesirable creation of new object each time you call the property getter. So, results of two sequential getter calls will not be equal:
interface IItem
{
bool IsGood { get; set; }
}
class ItemsContainer<T>
where T : IItem
{
private readonly List<T> items = new List<T>();
public IEnumerable<T> GoodItems
{
get { return items.Where(item => item.IsGood); }
}
// ...
}
// somewhere in code
class Item : IItem { /* ... */ }
var container = new ItemsContainer<Item>();
Console.WriteLine(container.GoodItems == container.GoodItems); // False; Oops!
You should avoid this side-effect:
class ItemsContainer<T>
where T : IItem
{
private readonly List<T> items;
private readonly Lazy<IEnumerable<T>> goodItems;
public ItemsContainer()
{
this.items = new List<T>();
this.goodItems = new Lazy<IEnumerable<T>>(() => items.Where(item => item.IsGood));
}
public IEnumerable<T> GoodItems
{
get { return goodItems.Value; }
}
// ...
}
or make a method instead of property:
public IEnumerable<T> GetGoodItems()
{
return _list.Where(x => x.IsGood);
}
Also, the property is not a good idea, if you want to provide snapshot of your items to the client code.
Internally, the first version gets compiled down to something that looks like this:
public IEnumerable<T> GoodItems
{
get
{
foreach (var item in _list)
if (item.IsGood)
yield return item;
}
}
Whereas the second one will now look something like:
public IEnumerable<T> GoodItems
{
get
{
foreach (var item in GoodItemsHelper)
yield return item;
}
}
private IEnumerable<T> GoodItemsHelper
{
get
{
foreach (var item in _list)
if (item.IsGood)
yield return item;
}
}
The Where clause in LINQ is implemented with deferred execution. So there's no need to apply the foreach (...) yield return ... pattern. You're making more work for yourself, and potentially for the runtime.
I don't know if the second version gets jitted to the same thing as the first. Semantically, the two are distinct in that the first does a single round of deferred execution while the second does two rounds. On those grounds I'd argue that the second would be more complex.
The real question you need to ask is: When you're exposing the IEnumerable, what guarantees are you making? Are you saying that you want to simply provide forward iteration? Or are you stating that your interface provides deferred execution?
In the code below, my intent for is to simply provide forward enumeration without random access:
private List<Int32> _Foo = new List<Int32>() { 1, 2, 3, 4, 5 };
public IEnumerable<Int32> Foo
{
get
{
return _Foo;
}
}
But here, I want to prevent unnecessary computation. I want my expensive computation to be performed only when a result is requested.
private List<Int32> _Foo = new List<Int32>() { 1, 2, 3, 4, 5 };
public IEnumerable<Int32> Foo
{
get
{
foreach (var item in _Foo)
{
var result = DoSomethingExpensive(item);
yield return result;
}
}
}
Even though both versions of Foo look identical on the outside, their internal implementation does different things. That's the part that you need to watch out for. When you use LINQ, you don't need to worry about deferring execution since most operators do it for you. In your own code, you may wish to go with the first or second depending on your needs.

Conditional typing in generic method

Consider the following (heavily simplified) code:
public T Function<T>() {
if (typeof(T) == typeof(string)) {
return (T) (object) "hello";
}
...
}
It's kind of absurd to first cast to object, then to T. But the compiler has no way of knowing that the previous test assured T is of type string.
What is the most elegant, idiomatic way of achieving this behavior in C# (which includes getting rid of the stupid typeof(T) == typeof(string), since T is string can't be used)?
Addendum: There is no return type variance in .net, so you can't make a function overload to type string (which, by the way, is just an example, but one reason why association end redefinition in polymorphism, e.g. UML, can't be done in c#). Obviously, the following would be great, but it doesn't work:
public T Function<T>() {
...
}
public string Function<string>() {
return "hello";
}
Concrete Example 1: Because there's been several attacks to the fact that a generic function that tests for specific types isn't generic, I'll try to provide a more complete example. Consider the Type-Square design pattern. Here follows a snippet:
public class Entity {
Dictionary<PropertyType, object> properties;
public T GetTypedProperty<T>(PropertyType p) {
var val = properties[p];
if (typeof(T) == typeof(string) {
(T) (object) p.ToString(this); // magic going here
}
return (T) TypeDescriptor.GetConverter(typeof(T)).ConvertFrom(val);
}
}
Concrete Example 2: Consider the Interpreter design pattern:
public class Expression {
public virtual object Execute() { }
}
public class StringExpression: Expression {
public override string Execute() { } // Error! Type variance not allowed...
}
Now let's use generics in Execute to allow the caller to force a return type:
public class Expression {
public virtual T Execute<T>() {
if(typeof(T) == typeof(string)) { // what happens when I want a string result from a non-string expression?
return (T) (object) do_some_magic_and_return_a_string();
} else if(typeof(T) == typeof(bool)) { // what about bools? any number != 0 should be True. Non-empty lists should be True. Not null should be True
return (T) (object) do_some_magic_and_return_a_bool();
}
}
}
public class StringExpression: Expressiong {
public override T Execute<T>() where T: string {
return (T) string_result;
}
}
If you're making these types of checks in a generic method, I'd rethink your design. The method is obviously not truly generic - if it were, you wouldn't need specific type checking...
Situations like this typically can be handled more cleanly by a redesign. One alternative is often to provide an overload of the appropriate type. Other design alternatives which avoid the type-specific behavior exist, as well, such as Richard Berg's suggestion of passing in a delegate.
using System;
using System.Collections.Generic;
using System.Linq;
namespace SimpleExamples
{
/// <summary>
/// Compiled but not run. Copypasta at your own risk!
/// </summary>
public class Tester
{
public static void Main(string[] args)
{
// Contrived example #1: pushing type-specific functionality up the call stack
var strResult = Example1.Calculate<string>("hello", s => "Could not calculate " + s);
var intResult = Example1.Calculate<int>(1234, i => -1);
// Contrived example #2: overriding default behavior with an alternative that's optimized for a certain type
var list1 = new List<int> { 1, 2, 3 };
var list2 = new int[] { 4, 5, 6 };
Example2<int>.DoSomething(list1, list2);
var list1H = new HashSet<int> { 1, 2, 3 };
Example2<int>.DoSomething<HashSet<int>>(list1H, list2, (l1, l2) => l1.UnionWith(l2));
}
}
public static class Example1
{
public static TParam Calculate<TParam>(TParam param, Func<TParam, TParam> errorMessage)
{
bool success;
var result = CalculateInternal<TParam>(param, out success);
if (success)
return result;
else
return errorMessage(param);
}
private static TParam CalculateInternal<TParam>(TParam param, out bool success)
{
throw new NotImplementedException();
}
}
public static class Example2<T>
{
public static void DoSomething(ICollection<T> list1, IEnumerable<T> list2)
{
Action<ICollection<T>, IEnumerable<T>> genericUnion = (l1, l2) =>
{
foreach (var item in l2)
{
l1.Add(item);
}
l1 = l1.Distinct().ToList();
};
DoSomething<ICollection<T>>(list1, list2, genericUnion);
}
public static void DoSomething<TList>(TList list1, IEnumerable<T> list2, Action<TList, IEnumerable<T>> specializedUnion)
where TList : ICollection<T>
{
/* stuff happens */
specializedUnion(list1, list2);
/* other stuff happens */
}
}
}
/// I confess I don't completely understand what your code was trying to do, here's my best shot
namespace TypeSquarePattern
{
public enum Property
{
A,
B,
C,
}
public class Entity
{
Dictionary<Property, object> properties;
Dictionary<Property, Type> propertyTypes;
public T GetTypedProperty<T>(Property p)
{
var val = properties[p];
var type = propertyTypes[p];
// invoke the cast operator [including user defined casts] between whatever val was stored as, and the appropriate type as
// determined by the domain model [represented here as a simple Dictionary; actual implementation is probably more complex]
val = Convert.ChangeType(val, type);
// now create a strongly-typed object that matches what the caller wanted
return (T)val;
}
}
}
/// Solving this one is a straightforward application of the deferred-execution patterns I demonstrated earlier
namespace InterpreterPattern
{
public class Expression<TResult>
{
protected TResult _value;
private Func<TResult, bool> _tester;
private TResult _fallback;
protected Expression(Func<TResult, bool> tester, TResult fallback)
{
_tester = tester;
_fallback = fallback;
}
public TResult Execute()
{
if (_tester(_value))
return _value;
else
return _fallback;
}
}
public class StringExpression : Expression<string>
{
public StringExpression()
: base(s => string.IsNullOrEmpty(s), "something else")
{ }
}
public class Tuple3Expression<T> : Expression<IList<T>>
{
public Tuple3Expression()
: base(t => t != null && t.Count == 3, new List<T> { default(T), default(T), default(T) })
{ }
}
}
Can you use as here?
T s = "hello" as T;
if(s != null)
return s;
I can't think of an "elegant" way to do this. As you say, the compiler can't know that the conditional has ensured that the type of T is string. As a result, it has to assume that, since there's no generalized way to convert from string to T, it's an error. object to T might succeed, so the compiler allows it.
I'm not sure I'd want an elegant way to express this. Although I can see where it'd be necessary to do explicit type checks like this in some situations, I think I'd want it to be cumbersome because it really is a bit of a hack. And I'd want it to stick out: "Hey! I'm doing something weird here!"
Ok, I took a run at it from several different angles and came up short. I would have to conclude that if your current implementation gets the job done you should take the win and move on. Short of some arcane emissions what you got is what you get.
But the compiler has no way of knowing
that the previous test assured T is of
type string.
Umm.... If I am not mistaken, generics is just code gen. The compiler generates a matching method for each distinct type found in the calling methods. So the compiler does know the type argument for the overload being called. Again; If I am not mistaken.
But overall, i think you are misusing the generic in this case, from what I can see, and as others have stated, there are more appropriate solutions..... which are unnamable unless you post code that completely specifies your requirements.
just my 2 pesos...

Passing a single item as IEnumerable<T>

Is there a common way to pass a single item of type T to a method which expects an IEnumerable<T> parameter? Language is C#, framework version 2.0.
Currently I am using a helper method (it's .Net 2.0, so I have a whole bunch of casting/projecting helper methods similar to LINQ), but this just seems silly:
public static class IEnumerableExt
{
// usage: IEnumerableExt.FromSingleItem(someObject);
public static IEnumerable<T> FromSingleItem<T>(T item)
{
yield return item;
}
}
Other way would of course be to create and populate a List<T> or an Array and pass it instead of IEnumerable<T>.
[Edit] As an extension method it might be named:
public static class IEnumerableExt
{
// usage: someObject.SingleItemAsEnumerable();
public static IEnumerable<T> SingleItemAsEnumerable<T>(this T item)
{
yield return item;
}
}
Am I missing something here?
[Edit2] We found someObject.Yield() (as #Peter suggested in the comments below) to be the best name for this extension method, mainly for brevity, so here it is along with the XML comment if anyone wants to grab it:
public static class IEnumerableExt
{
/// <summary>
/// Wraps this object instance into an IEnumerable<T>
/// consisting of a single item.
/// </summary>
/// <typeparam name="T"> Type of the object. </typeparam>
/// <param name="item"> The instance that will be wrapped. </param>
/// <returns> An IEnumerable<T> consisting of a single item. </returns>
public static IEnumerable<T> Yield<T>(this T item)
{
yield return item;
}
}
Well, if the method expects an IEnumerable you've got to pass something that is a list, even if it contains one element only.
passing
new[] { item }
as the argument should be enough I think
In C# 3.0 you can utilize the System.Linq.Enumerable class:
// using System.Linq
Enumerable.Repeat(item, 1);
This will create a new IEnumerable that only contains your item.
Your helper method is the cleanest way to do it, IMO. If you pass in a list or an array, then an unscrupulous piece of code could cast it and change the contents, leading to odd behaviour in some situations. You could use a read-only collection, but that's likely to involve even more wrapping. I think your solution is as neat as it gets.
In C# 3 (I know you said 2), you can write a generic extension method which might make the syntax a little more acceptable:
static class IEnumerableExtensions
{
public static IEnumerable<T> ToEnumerable<T>(this T item)
{
yield return item;
}
}
client code is then item.ToEnumerable().
This helper method works for item or many.
public static IEnumerable<T> ToEnumerable<T>(params T[] items)
{
return items;
}
I'm kind of surprised that no one suggested a new overload of the method with an argument of type T to simplify the client API.
public void DoSomething<T>(IEnumerable<T> list)
{
// Do Something
}
public void DoSomething<T>(T item)
{
DoSomething(new T[] { item });
}
Now your client code can just do this:
MyItem item = new MyItem();
Obj.DoSomething(item);
or with a list:
List<MyItem> itemList = new List<MyItem>();
Obj.DoSomething(itemList);
Either (as has previously been said)
MyMethodThatExpectsAnIEnumerable(new[] { myObject });
or
MyMethodThatExpectsAnIEnumerable(Enumerable.Repeat(myObject, 1));
As a side note, the last version can also be nice if you want an empty list of an anonymous object, e.g.
var x = MyMethodThatExpectsAnIEnumerable(Enumerable.Repeat(new { a = 0, b = "x" }, 0));
I agree with #EarthEngine's comments to the original post, which is that 'AsSingleton' is a better name. See this wikipedia entry. Then it follows from the definition of singleton that if a null value is passed as an argument that 'AsSingleton' should return an IEnumerable with a single null value instead of an empty IEnumerable which would settle the if (item == null) yield break; debate. I think the best solution is to have two methods: 'AsSingleton' and 'AsSingletonOrEmpty'; where, in the event that a null is passed as an argument, 'AsSingleton' will return a single null value and 'AsSingletonOrEmpty' will return an empty IEnumerable. Like this:
public static IEnumerable<T> AsSingletonOrEmpty<T>(this T source)
{
if (source == null)
{
yield break;
}
else
{
yield return source;
}
}
public static IEnumerable<T> AsSingleton<T>(this T source)
{
yield return source;
}
Then, these would, more or less, be analogous to the 'First' and 'FirstOrDefault' extension methods on IEnumerable which just feels right.
This is 30% faster than yield or Enumerable.Repeat when used in foreach due to this C# compiler optimization, and of the same performance in other cases.
public struct SingleSequence<T> : IEnumerable<T> {
public struct SingleEnumerator : IEnumerator<T> {
private readonly SingleSequence<T> _parent;
private bool _couldMove;
public SingleEnumerator(ref SingleSequence<T> parent) {
_parent = parent;
_couldMove = true;
}
public T Current => _parent._value;
object IEnumerator.Current => Current;
public void Dispose() { }
public bool MoveNext() {
if (!_couldMove) return false;
_couldMove = false;
return true;
}
public void Reset() {
_couldMove = true;
}
}
private readonly T _value;
public SingleSequence(T value) {
_value = value;
}
public IEnumerator<T> GetEnumerator() {
return new SingleEnumerator(ref this);
}
IEnumerator IEnumerable.GetEnumerator() {
return new SingleEnumerator(ref this);
}
}
in this test:
// Fastest among seqs, but still 30x times slower than direct sum
// 49 mops vs 37 mops for yield, or c.30% faster
[Test]
public void SingleSequenceStructForEach() {
var sw = new Stopwatch();
sw.Start();
long sum = 0;
for (var i = 0; i < 100000000; i++) {
foreach (var single in new SingleSequence<int>(i)) {
sum += single;
}
}
sw.Stop();
Console.WriteLine($"Elapsed {sw.ElapsedMilliseconds}");
Console.WriteLine($"Mops {100000.0 / sw.ElapsedMilliseconds * 1.0}");
}
As I have just found, and seen that user LukeH suggested too, a nice simple way of doing this is as follows:
public static void PerformAction(params YourType[] items)
{
// Forward call to IEnumerable overload
PerformAction(items.AsEnumerable());
}
public static void PerformAction(IEnumerable<YourType> items)
{
foreach (YourType item in items)
{
// Do stuff
}
}
This pattern will allow you to call the same functionality in a multitude of ways: a single item; multiple items (comma-separated); an array; a list; an enumeration, etc.
I'm not 100% sure on the efficiency of using the AsEnumerable method though, but it does work a treat.
Update: The AsEnumerable function looks pretty efficient! (reference)
Although it's overkill for one method, I believe some people may find the Interactive Extensions useful.
The Interactive Extensions (Ix) from Microsoft includes the following method.
public static IEnumerable<TResult> Return<TResult>(TResult value)
{
yield return value;
}
Which can be utilized like so:
var result = EnumerableEx.Return(0);
Ix adds new functionality not found in the original Linq extension methods, and is a direct result of creating the Reactive Extensions (Rx).
Think, Linq Extension Methods + Ix = Rx for IEnumerable.
You can find both Rx and Ix on CodePlex.
I recently asked the same thing on another post
Is there a way to call a C# method requiring an IEnumerable<T> with a single value? ...with benchmarking.
I wanted people stopping by here to see the brief benchmark comparison shown at that newer post for 4 of the approaches presented in these answers.
It seems that simply writing new[] { x } in the arguments to the method is the shortest and fastest solution.
This may not be any better but it's kind of cool:
Enumerable.Range(0, 1).Select(i => item);
Sometimes I do this, when I'm feeling impish:
"_".Select(_ => 3.14) // or whatever; any type is fine
This is the same thing with less shift key presses, heh:
from _ in "_" select 3.14
For a utility function I find this to be the least verbose, or at least more self-documenting than an array, although it'll let multiple values slide; as a plus it can be defined as a local function:
static IEnumerable<T> Enumerate (params T[] v) => v;
// usage:
IEnumerable<double> example = Enumerate(1.234);
Here are all of the other ways I was able to think of (runnable here):
using System;
using System.Collections.Generic;
using System.Linq;
public class Program {
public static IEnumerable<T> ToEnumerable1 <T> (T v) {
yield return v;
}
public static T[] ToEnumerable2 <T> (params T[] vs) => vs;
public static void Main () {
static IEnumerable<T> ToEnumerable3 <T> (params T[] v) => v;
p( new string[] { "three" } );
p( new List<string> { "three" } );
p( ToEnumerable1("three") ); // our utility function (yield return)
p( ToEnumerable2("three") ); // our utility function (params)
p( ToEnumerable3("three") ); // our local utility function (params)
p( Enumerable.Empty<string>().Append("three") );
p( Enumerable.Empty<string>().DefaultIfEmpty("three") );
p( Enumerable.Empty<string>().Prepend("three") );
p( Enumerable.Range(3, 1) ); // only for int
p( Enumerable.Range(0, 1).Select(_ => "three") );
p( Enumerable.Repeat("three", 1) );
p( "_".Select(_ => "three") ); // doesn't have to be "_"; just any one character
p( "_".Select(_ => 3.3333) );
p( from _ in "_" select 3.0f );
p( "a" ); // only for char
// these weren't available for me to test (might not even be valid):
// new Microsoft.Extensions.Primitives.StringValues("three")
}
static void p <T> (IEnumerable<T> e) =>
Console.WriteLine(string.Join(' ', e.Select((v, k) => $"[{k}]={v,-8}:{v.GetType()}").DefaultIfEmpty("<empty>")));
}
For those wondering about performance, while #mattica has provided some benchmarking information in a similar question referenced above, My benchmark tests, however, have provided a different result.
In .NET 7, yield return value is ~9% faster than new T[] { value } and allocates 75% the amount of memory. In most cases, this is already hyper-performant and is as good as you'll ever need.
I was curious if a custom single collection implementation would be faster or more lightweight. It turns out because yield return is implemented as IEnumerator<T> and IEnumerable<T>, the only way to beat it in terms of allocation is to do that in my implementation as well.
If you're passing IEnumerable<> to an outside library, I would strongly recommend not doing this unless you're very familiar with what you're building. That being said, I made a very simple (not-reuse-safe) implementation which was able to beat the yield method by 5ns and allocated only half as much as the array.
Because all tests were passed an IEnumerable<T>, value types generally performed worse than reference types. The best implementation I had was actually the simplest - you can look at the SingleCollection class in the gist I linked to. (This was 2ns faster than yield return, but allocated 88% of what the array would, compared to the 75% allocated for yield return.)
TL:DR; if you care about speed, use yield return item. If you really care about speed, use a SingleCollection.
The easiest way I'd say would be new T[]{item};; there's no syntax to do this. The closest equivalent that I can think of is the params keyword, but of course that requires you to have access to the method definition and is only usable with arrays.
Enumerable.Range(1,1).Select(_ => {
//Do some stuff... side effects...
return item;
});
The above code is useful when using like
var existingOrNewObject = MyData.Where(myCondition)
.Concat(Enumerable.Range(1,1).Select(_ => {
//Create my object...
return item;
})).Take(1).First();
In the above code snippet there is no empty/null check, and it is guaranteed to have only one object returned without afraid of exceptions. Furthermore, because it is lazy, the closure will not be executed until it is proved there is no existing data fits the criteria.
To be filed under "Not necessarily a good solution, but still...a solution" or "Stupid LINQ tricks", you could combine Enumerable.Empty<>() with Enumerable.Append<>()...
IEnumerable<string> singleElementEnumerable = Enumerable.Empty<string>().Append("Hello, World!");
...or Enumerable.Prepend<>()...
IEnumerable<string> singleElementEnumerable = Enumerable.Empty<string>().Prepend("Hello, World!");
The latter two methods are available since .NET Framework 4.7.1 and .NET Core 1.0.
This is a workable solution if one were really intent on using existing methods instead of writing their own, though I'm undecided if this is more or less clear than the Enumerable.Repeat<>() solution. This is definitely longer code (partly due to type parameter inference not being possible for Empty<>()) and creates twice as many enumerator objects, however.
Rounding out this "Did you know these methods exist?" answer, Array.Empty<>() could be substituted for Enumerable.Empty<>(), but it's hard to argue that makes the situation...better.
I'm a bit late to the party but I'll share my way anyway.
My problem was that I wanted to bind the ItemSource or a WPF TreeView to a single object. The hierarchy looks like this:
Project > Plot(s) > Room(s)
There was always going to be only one Project but I still wanted to Show the project in the Tree, without having to pass a Collection with only that one object in it like some suggested.
Since you can only pass IEnumerable objects as ItemSource I decided to make my class IEnumerable:
public class ProjectClass : IEnumerable<ProjectClass>
{
private readonly SingleItemEnumerator<AufmassProjekt> enumerator;
...
public IEnumerator<ProjectClass > GetEnumerator() => this.enumerator;
IEnumerator IEnumerable.GetEnumerator() => this.GetEnumerator();
}
And create my own Enumerator accordingly:
public class SingleItemEnumerator : IEnumerator
{
private bool hasMovedOnce;
public SingleItemEnumerator(object current)
{
this.Current = current;
}
public bool MoveNext()
{
if (this.hasMovedOnce) return false;
this.hasMovedOnce = true;
return true;
}
public void Reset()
{ }
public object Current { get; }
}
public class SingleItemEnumerator<T> : IEnumerator<T>
{
private bool hasMovedOnce;
public SingleItemEnumerator(T current)
{
this.Current = current;
}
public void Dispose() => (this.Current as IDisposable).Dispose();
public bool MoveNext()
{
if (this.hasMovedOnce) return false;
this.hasMovedOnce = true;
return true;
}
public void Reset()
{ }
public T Current { get; }
object IEnumerator.Current => this.Current;
}
This is probably not the "cleanest" solution but it worked for me.
EDIT
To uphold the single responsibility principle as #Groo pointed out I created a new wrapper class:
public class SingleItemWrapper : IEnumerable
{
private readonly SingleItemEnumerator enumerator;
public SingleItemWrapper(object item)
{
this.enumerator = new SingleItemEnumerator(item);
}
public object Item => this.enumerator.Current;
public IEnumerator GetEnumerator() => this.enumerator;
}
public class SingleItemWrapper<T> : IEnumerable<T>
{
private readonly SingleItemEnumerator<T> enumerator;
public SingleItemWrapper(T item)
{
this.enumerator = new SingleItemEnumerator<T>(item);
}
public T Item => this.enumerator.Current;
public IEnumerator<T> GetEnumerator() => this.enumerator;
IEnumerator IEnumerable.GetEnumerator() => this.GetEnumerator();
}
Which I used like this
TreeView.ItemSource = new SingleItemWrapper(itemToWrap);
EDIT 2
I corrected a mistake with the MoveNext() method.
I prefer
public static IEnumerable<T> Collect<T>(this T item, params T[] otherItems)
{
yield return item;
foreach (var otherItem in otherItems)
{
yield return otherItem;
}
}
This lets you call item.Collect() if you want the singleton, but it also lets you call item.Collect(item2, item3) if you want

Categories

Resources