Generate all the possible permutations of a class - c#

I have the following classes. For testing purpose, I would like to get all the possible permutations of the class Client. I know that the number can be very large, but this is not my problem for now.
Client: No (int), Name(string), Address(Address object)
Address: Street(string), Country(string), etc.
For a property of type int, I always try the same three values (-1, 0, 1), for string (null, string.Empty, "Hello World", etc.). For the base types, it works well. However, for the class Address, this is different.
In brief, I am trying to write a method generic enough to take any Type (class, etc.) and get all the possible permutations (in other words: public IEnumerable GetPermutations(Type myType)). With the help of .NET Reflection, this method would loop on all the settable properties.
Does anybody have an idea how to do that?
Thanks

The PEX testing framework does something along the lines. It attempts to provide several permutations of method parameters such that potentially useful test cases are covered.

Here's a class that may get you started, though I haven't tested it much. Note that this will only work for classes that have a no-args constructor, and won't work for some types of recursive classes (e.g. a class with a property of its own type, such as a tree). You also may want to pre-populate more classes in the static constructor.
public static class PermutationGenerator
{
private static class Permutation<T>
{
public static IEnumerable<T> Choices { get; set; }
}
static PermutationGenerator()
{
Permutation<int>.Choices = new List<int> { -1, 0, 1 }.AsReadOnly();
Permutation<string>.Choices = new List<string> { null, "", "Hello World" }.AsReadOnly();
}
public static IEnumerable<T> GetPermutations<T>()
{
if (Permutation<T>.Choices == null) {
var props = typeof(T).GetProperties().Where(p => p.CanWrite);
Permutation<T>.Choices = new List<T>(GeneratePermutations<T>(() => Activator.CreateInstance<T>(), props)).AsReadOnly();
}
return Permutation<T>.Choices;
}
private static IEnumerable GetPermutations(Type t) {
var method = typeof(PermutationGenerator).GetMethod("GetPermutations", new Type[] {}).MakeGenericMethod(t);
return (IEnumerable)(method.Invoke(null,new object[] {}));
}
private delegate T Generator<T>();
private static IEnumerable<T> GeneratePermutations<T>(Generator<T> generator, IEnumerable<PropertyInfo> props)
{
if (!props.Any())
{
yield return generator();
}
else
{
var prop = props.First();
var rest = props.Skip(1);
foreach (var propVal in GetPermutations(prop.PropertyType))
{
Generator<T> gen = () =>
{
var obj = generator();
prop.SetValue(obj, propVal, null);
return (T)obj;
};
foreach (var result in GeneratePermutations(gen, rest))
{
yield return result;
}
}
}
}
}

Most non-trivial dynamically allocated objects -- like strings -- don't have a finite amount of different "permutations" they can be in. That string can be as long as you want until your RAM runs out.
So this is really a completely Sisyphean task, and there's no point going on with it as stated unless you put a lot more heavy restrictions on what kind of permutations you're looking for.

You can have a look at PEX
http://research.microsoft.com/en-us/projects/pex/default.aspx
It's a whitebox test generation tool which integrates in Visual Studio.

As many have said, generating all permutations is computationally infeasible for non-trivial classes. What I have had to do, and had great success with, is generating all permutations of a class for a specific range of inputs; i.e., given a class with properties A, B, and C, I'd like to generate all permutations of A=1, A=2, B=1, C=3, and C=4, resulting in:
A=1, B=1, C=3
A=2, B=1, C=3
A=1, B=1, C=4
A=2, B=1, C=4
This kind of thing can be accomplished with recursive algorithms or some really elegant LINQ queries. There's a fairly exhaustive piece on that here, but its a good amount of programming and it really helps if you're boned up on your Set Theory.

That's like asking to move the Great Wall of China in 1 hour, into space. It cannot be done.
You would need to know what defines each permutation of every type, even types you didn't create, and that's impossible.

Related

Sorting a list with two parameters using CompareTo

I am presently sorting a C# list using the 'CompareTo' method in the object type contained in the list. I want to sort ascendingly all items by their WBS (Work Breakdown Structure) and I can manage this very well using the following code:
public int CompareTo(DisplayItemsEntity other)
{
string[] instanceWbsArray = this.WBS.Split('.');
string[] otherWbsArray = other.WBS.Split('.');
int result = 0;
for (int i = 0; i < maxLenght; i++)
{
if (instanceWbsArray[i].Equals(otherWbsArray[i]))
{
continue;
}
else
{
result = Int32.Parse(instanceWbsArray[i]).CompareTo(Int32.Parse(otherWbsArray[i]));
break;
}
}
return result;
}
Now, I would like to be able to sort considering more than one parameter, as in the project name alphabetically, before considering the second which would be the WBS. How can I do this?
I don't know the details of your class, so I'll provide an example using a list of strings and LINQ. OrderBy will order the strings alphabetically, ThenBy will order them by their lengths afterwards. You can adapt this sample to your needs easily enough.
var list = new List<string>
{
"Foo",
"Bar",
"Foobar"
};
var sortedList = list.OrderBy(i => i).
ThenBy(i => i.Length).
ToList();
What we generally do in cases like yours is this:
public int CompareTo( SomeClass other )
{
int result = this.SomeProperty.CompareTo( other.SomeProperty );
if( result != 0 )
return result;
result = this.AnotherProperty.CompareTo( other.AnotherProperty );
if( result != 0 )
return result;
[...]
return result;
}
P.S.
When posting code, please try to include only the code which is pertinent to your question. There is a load of stuff in the code that you posted that I did not need to read, and that in fact made my eyes hurt.
I like Eve's answer because of it's flexibility but I'm kinda surprised that no-one has mentioned creating a custom IComparer<T> instance
IComparer<T> is a generic interface that defines a method for comparing two instances of the type T. The advantage of using IComparer<T> is that you can create implementations for each sort order you commonly use and then use these as and when necessary. This allows you to create a default sort order in the types CompareTo() method and define alternative orders separately.
E.g.
public class MyComparer
: IComparer<YourType>
{
public int Compare(YourType x, YourType y)
{
//Add your comparison logic here
}
}
IComparer<T> is particularly useful for composition where you can do things like have a comparer which compares some properties of a given type using another comparer that operates on the type of the property.
It's also very useful if you ever need to define a sorting on a type you don't control. Another advantage it has is it doesn't require LINQ so can be used in older code (.Net 2.0 onwards)
First compare the project name alphabetically and if they are not equal return value, if not perform comparison based on second value
public int CompareTo(DisplayItemsEntity other)
{
if(other.ProjectName.CompareTo(this.ProjectName) != 0)
{
return other.ProjectName.CompareTo(this.ProjectName)
}
//else do the second comparison and return
return result;
}

Is a pipeline with a changing data type architecturally sound?

I'm working on the architecture for what is essentially a document parsing and analysis framework. Given the lines of the document, the framework will ultimately produce a large object (call it Document) representing the document.
Early filters in the pipeline will need to operate on a line-by-line basis. However, filters further down will need to transform (and ultimately produce) the Document object.
To implement this, I was thinking of using a filter definition like this:
public interface IFilter<in TIn, out TOut> {
TOut Execute(TIn data);
}
All filters will be registered with a PipelineManager class (as opposed to using the 'linked-list' style approach.) Before executing, PipelineManager will verify the integrity of the pipeline to ensure that no filter is given the wrong input type.
My question: Is it architecturally sound to have a pipeline with a changing data type (i.e. a good idea)?
P.S. The reason I'm implementing my application as a pipeline is because I feel it will be easy for plugin authors to replace/extend existing filters. Just swap out the filter you want to change with a different implementation, and you're set.
EDIT: Note, have removed other answer to replace with this wall'o'text grin
NINJAEDIT: Fun fact: Powershell (mentioned in #Loudenvier's answer) was once going to be named 'Monad' - also, found Wes Dyer's blog post on topic: The Marvels of Monads
One veryveryvery simplistic way of looking at this whole "Monad" thing is to think of it as a box with a very basic interface:
Return
Bind
Zero (optional)
The uses are similarly simple in concept - let's say you have a "thing":
You can wrap your "thing" in the box (this would be the "return") and have a "BoxOfThing"
You can give instructions on how to take the thing out of this box and put it into another box (Bind)
You can get an empty box (the "Zero": think of it as a sort of "no-op", like multiplying by one or adding zero)
(there are other rules, but these three are the most interesting)
The Bind bit is the really interesting part, and also the part that makes most people's heads explode; basically,
you're giving a specification of sorts for how to chain boxes together: Let's take a fairly simple Monad, the "Option"
or "Maybe" - a bit like Nullable<T>, but way cooler.
So everybody hates checking for null everywhere, but we're forced to due to the way reference types work; what we'd love
is to be able to code something like this:
var zipcodesNearby = order.Customer.Address.City.ZipCodes;
And either get back a valid answer if (customer is valid + address is valid + ...), or "Nothing" if any bit of that logic fails...but
no, we need to:
List<string> zipcodesNearBy = new List<string>();
if(goodOrder.Customer != null)
{
if(goodOrder.Customer.Address != null)
{
if(goodOrder.Customer.Address.City != null)
{
if(goodOrder.Customer.Address.City.ZipCodes != null)
{
zipcodesNearBy = goodOrder.Customer.Address.City.ZipCodes;
}
else { /* do something else? throw? */ }
}
else { /* do something else? throw? */ }
}
else { /* do something else? throw? */ }
}
else { /* do something else? throw? */ }
(note: you can also rely on null coalescing, when applicable - although it's pretty nasty looking)
List<string> nullCoalescingZips =
((((goodOrder ?? new Order())
.Customer ?? new Person())
.Address ?? new Address())
.City ?? new City())
.ZipCodes ?? new List<string>();
The Maybe monad "rules" might look a bit like:
(note:C# is NOT ideal for this type of Type-mangling, so it gets a bit wonky)
public static Maybe<T> Return(T value)
{
return ReferenceEquals(value, null) ? Maybe<T>.Nothing : new Maybe<T>() { Value = value };
}
public static Maybe<U> Bind<U>(Maybe<T> me, Func<T, Maybe<U>> map)
{
return me != Maybe<T>.Nothing ?
// extract, map, and rebox
map(me.Value) :
// We have nothing, so we pass along nothing...
Maybe<U>.Nothing;
}
But this leads to some NASTY code:
var result1 =
Maybe<string>.Bind(Maybe<string>.Return("hello"), hello =>
Maybe<string>.Bind(Maybe<string>.Return((string)null), doh =>
Maybe<string>.Bind(Maybe<string>.Return("world"), world =>
hello + doh + world).Value
).Value
);
Luckily, there's a neat shortcut: SelectMany is very roughly equivalent to "Bind":
If we implement SelectMany for our Maybe<T>...
public class Maybe<T>
{
public static readonly Maybe<T> Nothing = new Maybe<T>();
private Maybe() {}
public T Value { get; private set;}
public Maybe(T value) { Value = value; }
}
public static class MaybeExt
{
public static bool IsNothing<T>(this Maybe<T> me)
{
return me == Maybe<T>.Nothing;
}
public static Maybe<T> May<T>(this T value)
{
return ReferenceEquals(value, null) ? Maybe<T>.Nothing : new Maybe<T>(value);
}
// Note: this is basically just "Bind"
public static Maybe<U> SelectMany<T,U>(this Maybe<T> me, Func<T, Maybe<U>> map)
{
return me != Maybe<T>.Nothing ?
// extract, map, and rebox
map(me.Value) :
// We have nothing, so we pass along nothing...
Maybe<U>.Nothing;
}
// This overload is the one that "turns on" query comprehension syntax...
public static Maybe<V> SelectMany<T,U,V>(this Maybe<T> me, Func<T, Maybe<U>> map, Func<T,U,V> selector)
{
return me.SelectMany(x => map(x).SelectMany(y => selector(x,y).May()));
}
}
Now we can piggyback on LINQ comprehension syntax!
var result1 =
from hello in "Hello".May()
from oops in ((string)null).May()
from world in "world".May()
select hello + oops + world;
// prints "Was Nothing!"
Console.WriteLine(result1.IsNothing() ? "Was Nothing!" : result1.Value);
var result2 =
from hello in "Hello".May()
from space in " ".May()
from world in "world".May()
select hello + space + world;
// prints "Hello world"
Console.WriteLine(result2.IsNothing() ? "Was Nothing!" : result2.Value);
var goodOrder = new Order { Customer = new Person { Address = new Address { City = new City { ZipCodes = new List<string>{"90210"}}}}};
var badOrder = new Order { Customer = new Person { Address = null }};
var zipcodesNearby =
from ord in goodOrder.May()
from cust in ord.Customer.May()
from add in cust.Address.May()
from city in add.City.May()
from zip in city.ZipCodes.May()
select zip;
// prints "90210"
Console.WriteLine(zipcodesNearby.IsNothing() ? "Nothing!" : zipcodesNearby.Value.FirstOrDefault());
var badZipcodesNearby =
from ord in badOrder.May()
from cust in ord.Customer.May()
from add in cust.Address.May()
from city in add.City.May()
from zip in city.ZipCodes.May()
select zip;
// prints "Nothing!"
Console.WriteLine(badZipcodesNearby.IsNothing() ? "Nothing!" : badZipcodesNearby.Value.FirstOrDefault());
Hah, just realized I forgot to mention the whole point of this...so basically, once you've figured out what the equivalent for "bind" is at each stage of your pipeline, you can use the same type of pseudomonadic code to handle the wrapping, unwrapping, and processing of each of your type transformations.
This won't answer your question, but a great place to look for inspiration on pipelines in the .NET world is PowerShell. They've implemented the pipeline model in a very clever way, and the objects flowing the pipeline will change all the time.
I've had to produce a Database to PDF document creation pipeline in the past and did it as PowerShell commandlets. It was so extensible that years later it is still being actively used and developed, it only migrated from PowerShell 1 to 2 and now possibly to 3.
You can get great ideas here: http://blogs.technet.com/b/heyscriptingguy/

Performance of Linq query by type

A discussion has come up at work:
We've got a class that has an IList. Fact is an abstract base class, and there are several concrete subclasses (PopulationFact, GdpFact, etc).
Originally we'd query for a given fact in this fashion, i.e. by type:
.Facts.FirstOrDefault(x => x.Year == 2011 && x is GdpFact)
Now, however, the question's been raised whether we should introduce a FactType enum instead to do
.Facts.FirstOrDefault(x => x.Year == 2011 && x.FactType == FactType.Gdp)
The suggestion has been raised because it is supposedly faster. I'll admit that I've not written any tests to try and discern the difference in performance, but I have two questions:
1) Is 'querying on type' like this inherently bad?
2) Isn't adding a FactType enum just superfluous anyway, given that facts are strongly typed?
UPDATE
To clarify, this is LINQ to objects and GdpFact:Fact.
UPDATE 2
We've measured using current typical data (4 facts) and the results are in:
lookup on enum: 0.29660000000000003 milliseconds
lookup on type: 0.24530000000000002 milliseconds
So type lookup is faster in this context! I will choose my accepted answer carefully.
I've done a test, my results for 1000000 iterations are approximately
ByCast 166ms
ByType 84ms
ByEnum 98ms
So the enum is in fact superfluous and slower but, not by much. This should not be too suprising, the type system is fundamental to the .Net Framework.
Test code transcribed below, apologies for errata
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
class Program
{
private enum TypeOfFact
{
Gdp,
Other
}
private abstract class Fact
{
public virtual int Year { get; set; }
public abstract TypeOfFact FactType { get; }
}
private class GdpFact : Fact
{
public override TypeOfFact FactType
{
get { return TypeOfFact.Gdp; }
}
}
private class OtherFact : Fact
{
public override TypeOfFact FactType
{
get { return TypeOfFact.Other; }
}
}
static void Main()
{
Ilist<Fact> facts = new List<Fact>
{
new GdpFact { Year = 2010 },
new OtherFact { Year = 2010 },
new GdpFact { Year = 2009 },
new OtherFact { Year = 2009 },
new GdpFact { Year = 2011 },
new OtherFact { Year = 2011 },
};
const int interations = 1000000;
var funcs = new List<Func<IList<Fact>, Fact>>
{
ByList,
ByType,
ByEnum
};
// Warmup
foreach (var func in funcs)
{
Measure(5, func, facts);
}
// Results
foreach (var result in funcs.Select(f => new
{
Description = f.Method.Name,
Ms = Measure(iterations, f, facts)
}))
{
Console.WriteLine(
"{0} time = {1}ms",
result.Description,
result.Ms);
}
}
private static long Measure(
int iterations,
Func<IList<Fact>, Fact> func,
IList<Fact> facts)
{
var stopwatch = new Stopwatch();
stopwatch.Start();
for (var i = 0; i < iterations; i++)
{
func.Invoke(facts);
}
stopwatch.Stop();
return stopwatch.ElapsedMilliseconds;
}
private static Fact ByType(IList<Fact> facts)
{
return facts.FirstOrDefault(f =>
f.Year == 2011 && f is GdpFact);
}
private static Fact ByEnum(IList<Fact> facts)
{
return facts.FirstOrDefault(f =>
f.Year == 2011 && f.FactType == TypeOfFact.Gdp);
}
private static Fact ByCast(IList<Fact> facts)
{
return facts.OfType<GdpFact>()
.FirstOrDefault(f => f.Year == 2011);
}
}
This question seems relevant.
All type of preformance related questions are strictly dependent on concrete application context, so may be answer(s) provided here will be partially right/wrong for your concrete case.
Having this in mind:
Checking enum value should be reasonably faster then checking for type, as in first case, you just check for equality 2 integers (enum values).
But that introduce one more field in the object, that has to be tracked to have correct value (unit test), which you do not need in second case, as CLR cares about correct type initialization.
I think it's better that you profile your ideas against relevant amount of data, that your app usually operates over, and will come out with correct idea for you.
I think your original approach is fine. the 'is' keyword is provided for this purpose. MSDN does not discourage the use of 'is'. Using an enum seems to be over-engineering. We should try and keep code simple. Fewer the lines of code the better it is in most situations.
Is this maybe a solution looking for a problem?
I think having both concrete subtypes and an enum in the base type could potentially obfuscate your design. You could imagine someone coming along later and writing a new concrete class but not realising they needed to add to the enum as well...
Unless you find you have a specific problem to do with performance, I'd be tempted to prioritise clarity instead. Therefore if you need different concrete classes (and I'm assuming you do since that's how you've coded it to start with) then I'd stick with your types rather than move to an enum.
It's possible that checking an enum value will be faster than a runtime type-check, but...
It's a micro-optimisation -- you're unlikely to notice much perf difference in real-world scenarios.
It makes things more complicated, and more complicated means more likely to break.
For example, what's to stop you, or one of your colleagues, accidentally doing something like this?
public class PopulationFact : Fact
{
public FactType FactType = FactType.GdpFact; // should be PopulationFact
}
I'd stick with the type-check. There's actually a built-in LINQ method that'll do it for you:
.Facts.FirstOrDefault(x => x.Year == 2011).OfType<GdpFact>()

Create an enumeration of one

If I want an empty enumeration, I can call Enumerable.Empty<T>(). But what if I want to convert a scalar type to an enumeration?
Normally I'd write new List<string> {myString} to pass myString to a function that accepts IEnumerable<string>. Is there a more LINQ-y way?
You can use Repeat:
var justOne = Enumerable.Repeat(value, 1);
Or just an array of course:
var singleElementArray = new[] { value };
The array version is mutable of course, whereas Enumerable.Repeat isn't.
Perhaps the shortest form is
var sequence = new[] { value };
There is, but it's less efficient than using a List or Array:
// an enumeration containing only the number 13.
var oneIntEnumeration = Enumerable.Repeat(13, 1);
You can also write your own extension method:
public static class Extensions
{
public static IEnumerable<T> AsEnumerable<T>(this T item)
{
yield return item;
}
}
Now I haven't done that, and now that I know about Enumerable.Repeat, I probably never will (learn something new every day). But I have done this:
public static IEnumerable<T> MakeEnumerable<T>(params T[] items)
{
return items;
}
And this, of course, works if you call it with a single argument. But maybe there's something like this in the framework already, that I haven't discovered yet.

Practical example where Tuple can be used in .Net 4.0?

I have seen the Tuple introduced in .Net 4 but I am not able to imagine where it can be used. We can always make a Custom class or Struct.
That's the point - it is more convenient not to make a custom class or struct all the time. It is an improvement like Action or Func... you can make this types yourself, but it's convenient that they exist in the framework.
With tuples you could easily implement a two-dimensional dictionary (or n-dimensional for that matter). For example, you could use such a dictionary to implement a currency exchange mapping:
var forex = new Dictionary<Tuple<string, string>, decimal>();
forex.Add(Tuple.Create("USD", "EUR"), 0.74850m); // 1 USD = 0.74850 EUR
forex.Add(Tuple.Create("USD", "GBP"), 0.64128m);
forex.Add(Tuple.Create("EUR", "USD"), 1.33635m);
forex.Add(Tuple.Create("EUR", "GBP"), 0.85677m);
forex.Add(Tuple.Create("GBP", "USD"), 1.55938m);
forex.Add(Tuple.Create("GBP", "EUR"), 1.16717m);
forex.Add(Tuple.Create("USD", "USD"), 1.00000m);
forex.Add(Tuple.Create("EUR", "EUR"), 1.00000m);
forex.Add(Tuple.Create("GBP", "GBP"), 1.00000m);
decimal result;
result = 35.0m * forex[Tuple.Create("USD", "EUR")]; // USD 35.00 = EUR 26.20
result = 35.0m * forex[Tuple.Create("EUR", "GBP")]; // EUR 35.00 = GBP 29.99
result = 35.0m * forex[Tuple.Create("GBP", "USD")]; // GBP 35.00 = USD 54.58
There's an excellent article in MSDN magazine that talks about the belly-aching and design considerations that went into adding Tuple to the BCL. Choosing between a value type and a reference type is particularly interesting.
As the article makes clear, the driving force behind Tuple was so many groups inside of Microsoft having a use for it, the F# team up front. Although not mentioned, I reckon that the new "dynamic" keyword in C# (and VB.NET) had something to do with it as well, tuples are very common in dynamic languages.
It is otherwise not particularly superior to creating your own poco, at least you can give the members a better name.
UPDATE: due for a big revision in C# version 7, now getting a lot more syntax love. Preliminary announcement in this blog post.
Here's a small example - say you have a method that needs to lookup a user's handle and email address, given a user Id. You can always make a custom class that contains that data, or use a ref / out parameter for that data, or you can just return a Tuple and have a nice method signature without having to create a new POCO.
public static void Main(string[] args)
{
int userId = 0;
Tuple<string, string> userData = GetUserData(userId);
}
public static Tuple<string, string> GetUserData(int userId)
{
return new Tuple<string, string>("Hello", "World");
}
I used a tuple to solve Problem 11 of Project Euler:
class Grid
{
public static int[,] Cells = { { 08, 02, 22, // whole grid omitted
public static IEnumerable<Tuple<int, int, int, int>> ToList()
{
// code converts grid to enumeration every possible set of 4 per rules
// code omitted
}
}
Now I can solve the whole problem with:
class Program
{
static void Main(string[] args)
{
int product = Grid.ToList().Max(t => t.Item1 * t.Item2 * t.Item3 * t.Item4);
Console.WriteLine("Maximum product is {0}", product);
}
}
I could have used a custom type for this, but it would have looked exactly like Tuple.
C#'s tuple syntax is ridiculously bulky, so tuples are painful to declare. And it doesn't have pattern matching, so they're also painful to use.
But occasionally, you just want an ad-hoc grouping of objects without creating a class for it. For example, let's say I wanted to aggregate a list, but I wanted two values instead of one:
// sum and sum of squares at the same time
var x =
Enumerable.Range(1, 100)
.Aggregate((acc, x) => Tuple.Create(acc.Item1 + x, acc.Item2 + x * x));
Instead of combining a collection of values into a single result, let's expand a single result into a collection of values. The easiest way to write this function is:
static IEnumerable<T> Unfold<T, State>(State seed, Func<State, Tuple<T, State>> f)
{
Tuple<T, State> res;
while ((res = f(seed)) != null)
{
yield return res.Item1;
seed = res.Item2;
}
}
f converts some state into a tuple. We return the first value from the tuple and set our new state to the second value. This allows us to retain state throughout the computation.
You use it as such:
// return 0, 2, 3, 6, 8
var evens =
Unfold(0, state => state < 10 ? Tuple.Create(state, state + 2) : null)
.ToList();
// returns 0, 1, 1, 2, 3, 5, 8, 13, 21, 34
var fibs =
Unfold(Tuple.Create(0, 1), state => Tuple.Create(state.Item1, Tuple.Create(state.Item2, state.Item1 + state.Item2)))
.Take(10).ToList();
evens is fairly straightforward, but fibs is a little more clever. Its state is actually a tuple which holds fib(n-2) and fib(n-1) respectively.
I don't like the abuse of them, since they produce code that doesn't explain itself, but they're awesome to implement on-the-fly compound keys, since they implement IStructuralEquatable and IStructuralComparable (to use both for lookup and ordering purposes).
And they combine all of their items' hashcodes, internally; for example, here is Tuple's GetHashCode (taken from ILSpy):
int IStructuralEquatable.GetHashCode(IEqualityComparer comparer)
{
return Tuple.CombineHashCodes(comparer.GetHashCode(this.m_Item1), comparer.GetHashCode(this.m_Item2), comparer.GetHashCode(this.m_Item3));
}
Tuples are great for doing multiple async IO operations at a time and returning all the values together. Here is the examples of doing it with and without Tuple. Tuples can actually make your code clearer!
Without (nasty nesting!):
Task.Factory.StartNew(() => data.RetrieveServerNames())
.ContinueWith(antecedent1 =>
{
if (!antecedent1.IsFaulted)
{
ServerNames = KeepExistingFilter(ServerNames, antecedent1.Result);
Task.Factory.StartNew(() => data.RetrieveLogNames())
.ContinueWith(antecedent2 =>
{
if (antecedent2.IsFaulted)
{
LogNames = KeepExistingFilter(LogNames, antecedent2.Result);
Task.Factory.StartNew(() => data.RetrieveEntryTypes())
.ContinueWith(antecedent3 =>
{
if (!antecedent3.IsFaulted)
{
EntryTypes = KeepExistingFilter(EntryTypes, antecedent3.Result);
}
});
}
});
}
});
With Tuple
Task.Factory.StartNew(() =>
{
List<string> serverNames = data.RetrieveServerNames();
List<string> logNames = data.RetrieveLogNames();
List<string> entryTypes = data.RetrieveEntryTypes();
return Tuple.Create(serverNames, logNames, entryTypes);
}).ContinueWith(antecedent =>
{
if (!antecedent.IsFaulted)
{
ServerNames = KeepExistingFilter(ServerNames, antecedent.Result.Item1);
LogNames = KeepExistingFilter(LogNames, antecedent.Result.Item2);
EntryTypes = KeepExistingFilter(EntryTypes, antecedent.Result.Item3);
}
});
If you were using an anonymous function with an implied type anyway then you aren't making the code less clear by using the Tuple. Retuning a Tuple from a method? Use sparingly when code clarity is key, in my humble opinion. I know functional programming in C# is hard to resist, but we have to consider all of those old clunky "object oriented" C# programmers.
Tuples are heavily used in functional languages which can do more things with them, now F# is a 'official' .net language you may want to interoperate with it from C# and pass them between code written in two languages.
I tend to avoid Tuple for most scenarios since it hurts readability. However, Tuple is useful when you need to group unrelated data.
For example, suppose you have a list of cars and the cities in which they were purchased:
Mercedes, Seattle
Mustang, Denver
Mercedes, Seattle
Porsche, Seattle
Tesla, Seattle
Mercedes, Seattle
You want to aggregate the counts for each car per city:
Mercedes, Seattle [3]
Mustang, Denver [1]
Porsche, Seattle [1]
Tesla, Seattle [1]
To do this, you create a Dictionary. You have a few options:
Create a Dictionary<string, Dictionary<string, int>>.
Create a Dictionary<CarAndCity, int>.
Create a Dictionary<Tuple<string, string>, int>.
Readability is lost with the first option. It will require you to write a lot more code.
The second option works and is succinct, but car and city aren't really related and probably don't belong in a class together.
The third option is succinct and clean. It's a good use of Tuple.
A few examples off the top of my head:
An X and Y location (and Z if you like)
a Width and Height
Anything measured over time
For example you wouldn't want to include System.Drawing in a web application just to use Point/PointF and Size/SizeF.
You should be very careful with using Tuple and probably think twice before do this. From my previous experience I found out that using Tuple makes code very difficult to read and support in the future. A while ago, I had to fix some code where tuples were used almost everywhere. Instead of thinking about proper object models, they just used tuples. That was nightmare... sometimes I wanted to kill the guy who wrote the code...
Don't want to say that you shouldn't use Tuple and it's evil or something and I'm hundred percent sure there are some tasks where the Tuple is the best candidate to be used, but probably you should think again, do you REALLY need it?
The best use for Tuples I have found is when needing to return more than 1 type of object from a method, you know what object types and number they will be, and it is not a long list.
Other simple alternatives would be using an 'out' parameter
private string MyMethod(out object)
or making a Dictionary
Dictionary<objectType1, objectType2>
Using a Tuple however saves either creating the 'out' object or having to essentially look-up the entry in the dictionary;
Just found the solution of one of my issues in Tuple. It is like declaring a class in scope of a method, but with lazy declaration of its fields names. You operate with collections of tuples, its single instances and then create a collection of anonymous type with the required field names, basing on your tuple. This avoids you from creating the new class for this purpose.
The task is to write a JSON response from LINQ without any additional classes:
//I select some roles from my ORM my with subrequest and save results to Tuple list
var rolesWithUsers = (from role in roles
select new Tuple<string, int, int>(
role.RoleName,
role.RoleId,
usersInRoles.Where(ur => ur.RoleId == role.RoleId).Count()
));
//Then I add some new element required element to this collection
var tempResult = rolesWithUsers.ToList();
tempResult.Add(new Tuple<string, int, int>(
"Empty",
-1,
emptyRoleUsers.Count()
));
//And create a new anonimous class collection, based on my Tuple list
tempResult.Select(item => new
{
GroupName = item.Item1,
GroupId = item.Item2,
Count = item.Item3
});
//And return it in JSON
return new JavaScriptSerializer().Serialize(rolesWithUsers);
Of cause we could do this with declaring a new Class for my groups, but the idea to create such an anonimous collections without declaring of new classes.
Well in my case, I had to use a Tuple when I found out that we cannot use out parameter in an asynchronous method. Read about it here. I also needed a different return type. So I used a Tuple instead as my return type and marked the method as async.
Sample code below.
...
...
// calling code.
var userDetails = await GetUserDetails(userId);
Console.WriteLine("Username : {0}", userDetails.Item1);
Console.WriteLine("User Region Id : {0}", userDetails.Item2);
...
...
private async Tuple<string,int> GetUserDetails(int userId)
{
return new Tuple<string,int>("Amogh",105);
// Note that I can also use the existing helper method (Tuple.Create).
}
Read more about Tuple here.
Hope this helps.
Changing shapes of objects when you need to send them across wire or pass to different layer of application and multiple objects get merged into one:
Example:
var customerDetails = new Tuple<Customer, List<Address>>(mainCustomer, new List<Address> {mainCustomerAddress}).ToCustomerDetails();
ExtensionMethod:
public static CustomerDetails ToCustomerDetails(this Tuple<Website.Customer, List<Website.Address>> customerAndAddress)
{
var mainAddress = customerAndAddress.Item2 != null ? customerAndAddress.Item2.SingleOrDefault(o => o.Type == "Main") : null;
var customerDetails = new CustomerDetails
{
FirstName = customerAndAddress.Item1.Name,
LastName = customerAndAddress.Item1.Surname,
Title = customerAndAddress.Item1.Title,
Dob = customerAndAddress.Item1.Dob,
EmailAddress = customerAndAddress.Item1.Email,
Gender = customerAndAddress.Item1.Gender,
PrimaryPhoneNo = string.Format("{0}", customerAndAddress.Item1.Phone)
};
if (mainAddress != null)
{
customerDetails.AddressLine1 =
!string.IsNullOrWhiteSpace(mainAddress.HouseName)
? mainAddress.HouseName
: mainAddress.HouseNumber;
customerDetails.AddressLine2 =
!string.IsNullOrWhiteSpace(mainAddress.Street)
? mainAddress.Street
: null;
customerDetails.AddressLine3 =
!string.IsNullOrWhiteSpace(mainAddress.Town) ? mainAddress.Town : null;
customerDetails.AddressLine4 =
!string.IsNullOrWhiteSpace(mainAddress.County)
? mainAddress.County
: null;
customerDetails.PostCode = mainAddress.PostCode;
}
...
return customerDetails;
}
An out parameter is great when there are only a few values that need to be returned,
but when you start encountering 4, 5, 6, or more values that need to be returned, it
can get unwieldy. Another option for returning multiple values is to create and return
a user-defined class/structure or to use a Tuple to package up all the values that need
to be returned by a method.
The first option, using a class/structure to return the values, is straightforward. Just
create the type (in this example it is a structure) like so:
public struct Dimensions
{
public int Height;
public int Width;
public int Depth;
}
The second option, using a Tuple, is an even more elegant solution than using a userdefined
object. A Tuple can be created to hold any number of values of varying types.
In addition, the data you store in the Tuple is immutable; once you add the data to
the Tuple through the constructor or the static Create method, that data cannot be
changed.
Tuples can accept up to and including eight separate values. If you need to return
more than eight values, you will need to use the special Tuple class:
Tuple Class
When creating a Tuple with more than eight values, you cannot use the static Create
method—you must instead use the constructor of the class. This is how you would
create a Tuple of 10 integer values:
var values = new Tuple<int, int, int, int, int, int, int, Tuple<int, int, int>> (
1, 2, 3, 4, 5, 6, 7, new Tuple<int, int, int> (8, 9, 10));
Of course, you can continue to add more Tuples to the end of each embedded Tuple,
creating any size Tuple that you need.
Only for prototyping - Tuples are meaningless. It convenient to use them but it's a shortcut only! For prototypes - fine. Just be sure to delete this code later.
It easy to write, hard to read. It has no visible advantages over classes, inner classes , anonymous classes etc.
Well I tried 3 ways to solve the same problem in C#7 and I have found a use case for Tuples.
Working with dynamic data in web projects can sometimes be a pain when mapping etc.
I like the way the Tuple just auto mapped onto item1, item2, itemN which seems more robust to me than using array indexes where you might get caught on an out of index item or using the anonymous type where you may misspell a property name.
It feels like a DTO has been created for free just by using a Tuple and I can access all the properties using itemN which feels more like static typing without having to create a separate DTO for that purpose.
using System;
namespace Playground
{
class Program
{
static void Main(string[] args)
{
var tuple = GetTuple();
Console.WriteLine(tuple.Item1);
Console.WriteLine(tuple.Item2);
Console.WriteLine(tuple.Item3);
Console.WriteLine(tuple);
Console.WriteLine("---");
var dyn = GetDynamic();
Console.WriteLine(dyn.First);
Console.WriteLine(dyn.Last);
Console.WriteLine(dyn.Age);
Console.WriteLine(dyn);
Console.WriteLine("---");
var arr = GetArray();
Console.WriteLine(arr[0]);
Console.WriteLine(arr[1]);
Console.WriteLine(arr[2]);
Console.WriteLine(arr);
Console.Read();
(string, string, int) GetTuple()
{
return ("John", "Connor", 1);
}
dynamic GetDynamic()
{
return new { First = "John", Last = "Connor", Age = 1 };
}
dynamic[] GetArray()
{
return new dynamic[] { "John", "Connor", 1 };
}
}
}
}

Categories