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 };
}
}
}
}
Related
Sorry, I think I was not clear earlier. I am trying to do as O.R.mapper says below- create a list of arbitrary variables and then get their values later in foreach loop.
Moreover, all variables are of string type so I think can come in one list. Thanks.
Is there a way to store variables in a list or array then then loop through them later.
For example: I have three variables in a class c named x,y and Z.
can I do something like:
public List Max_One = new List {c.x,c.y,c.z}
and then later in the code
foreach (string var in Max_One)
{
if ((var < 0) | (var > 1 ))
{
// some code here
}
}
Is there a particular reason why you want to store the list of variables beforehand? If it is sufficient to reuse such a list whenever you need it, I would opt for creating a property that returns an IEnumerable<string>:
public IEnumerable<string> Max_One {
get {
yield return c.x;
yield return c.y;
yield return c.z;
}
}
The values returned in this enumerable would be retrieved only when the property getter is invoked. Hence, the resulting enumerable would always contain the current values of c.x, c.y and c.z.
You can then iterate over these values with a foreach loop as alluded to by yourself in your question.
This might not be practical if you need to gradually assemble the list of variables; in that case, you might have to work with reflection. If this is really required, please let me know; I can provide an example for that, but it will become more verbose and complex.
Yes, e.g. if they are all strings:
public List<string> Max_One = new List<string> {c.x,c.y,c.z};
This uses the collection initializer syntax.
It doesn't make sense to compare a string to an int, though. This is a valid example:
foreach (string var in Max_One)
{
if (string.IsNullOrEmpty(var))
{
// some code here
}
}
If your properties are numbers (int, for example) you can do this:
List<int> Max_One = new List<int> { c.x, c.y, c.Z };
and use your foreach like this
foreach(int myNum in Max_One) { ... } //you can't name an iterator 'var', it's a reserved word
Replace int in list declaration with the correct numeric type (double, decimal, etc.)
You could try using:
List<object> list = new List<object>
{
c.x,
c.y,
c.z
};
I will answer your question in reverse way
To start with , you cannot name your variable with "var" since it is reserved name. So what you can do for the foreach is
foreach (var x in Max_One)
{
if ((x< 0) || (x> 1 ))
{
// some code here
}
}
if you have .Net 3.0 and later framework, you can use "var" to define x as a member of Max_One list without worrying about the actual type of x. if you have older than the version 3.0 then you need to specify the datatype of x, and in this case your code is valid (still risky though)
The last point (which is the your first point)
public List Max_One = new List {c.x,c.y,c.z}
There are main thing you need to know , that is in order to store in a list , the members must be from the same datatype, so unless a , b , and c are from the same datatype you cannot store them in the same list EXCEPT if you defined the list to store elements of datatype "object".
If you used the "Object" method, you need to cast the elements into the original type such as:
var x = (int) Max_One[0];
You can read more about lists and other alternatives from this website
http://www.dotnetperls.com/collections
P.s. if this is a homework, then you should read more and learn more from video tutorials and books ;)
Ive just seen a piece of code that uses a generic list class to instantiate itself in the following manner:
var foo = new List<string>(){"hello", "goodbye"};
The curly braces after the contructor are especially confusing. It reminds me somewhat of
var bar = new string[]{"hi","bye"};
but in the past i've wouldve always used:
var foo = new List<string>(new []{"hello", "goodbye"});
Has anybody got a link explaining the syntax in the first line of code? I wouldnt even know where to begin with googling it.
As others have pointed out, that is a collection initializer. Some other features you might not be aware of that were added to C# 3:
A collection initializer constructor may omit the parentheses if the argument list is empty. So new List<int> { 10, 20, 30 } is fine.
An array initialized with an array initializer may in some cases omit the type. For example, var myInts = new[] { 10, 20, 30}; infers that myInts is int[].
Objects may be initialized using a similar object initializer syntax. var c = new Customer() { Name = "Fred" }; is the same as var temp = new Customer(); temp.Name = "Fred"; var c = temp;
The point of these features is to (1) make more things that used to require statements into things that require only expressions; LINQ likes things to be expressions, and (2) to enable richer type inference, particularly for anonymous types.
Finally: there has been some confusion in some of the answers and comments regarding what is required for a collection initializer. To be used with a collection initializer the type must (1) implement IEnumerable (so that we know it is a collection) and (2) have an Add method (so that we can add stuff to it.)
See
http://blogs.msdn.com/b/madst/archive/2006/10/10/what-is-a-collection_3f00_.aspx
for additional thoughts on the design of the feature.
here you go. The keyword is "Array Initializers".
http://msdn.microsoft.com/en-us/library/aa664573(v=vs.71).aspx
or rather "Collection Initializers"
http://msdn.microsoft.com/en-us/library/bb384062.aspx
This is a collection initializer: http://msdn.microsoft.com/en-us/library/bb384062.aspx
The type so initialized must implement IEnumerable and have an Add method. The items in the curly-brace list are passed to the add method; different items in the list could be passed to different Add methods. If there's an Add overload with more than one argument, you put the multiple arguments in a comma-separated list enclosed in curly braces.
For example:
class MyWeirdCollection : IEnumerable
{
public void Add(int i) { /*...*/ }
public void Add(string s) { /*...*/ }
public void Add(int i, string s) { /*...*/ }
//IEnumerable implementation omitted for brevity
}
This class could be initialized thus:
var weird = new MyWeirdCollection { 1, "Something", {5, "Something else"} };
This compiles to something like this:
var temp = new MyWeirdCollection();
temp.Add(1);
temp.Add("Something");
temp.Add(5, "Something else");
var weird = temp;
In his blog post (link posted by Eric Lippert in the comments), Mads Torgersen expresses this concisely:
The list you provide is not a “list of elements to add”, but a “list of sets of arguments to Add methods”. ...[W]e do separate overload resolution against Add methods for each entry in the list.
In the third line of code you provided you are making a new string array, and then passing that string array to the list. The list will then add each of those items to the list. This involves the extra overhead of allocating the array, populating it, and then discarding it.
There is a mechanism for a class to define how to use Collection Initializers to populate itself. (See the other answers) I have never found the need to utilize this for my own classes, but existing data structures such as List, Dictionary, often define them, and they are useful to use.
This is a collection initializer. You can use it on collections with an Add method.
The pair of parentheses before the curly braces is optional.
This is very convenient, because you can use it on collections other than lists, for example on dictionaries:
var x = new Dictionary<int,string> {{1, "hello"}, {2, "world"}};
This lets you avoid a lengthier initialization sequence:
var x = new Dictionary<int,string>();
x.Add(1, "hello");
x.Add(2, "world");
The only advantage I can see to do:
var s = new ClassA();
over
ClassA s = new ClassA();
Is that later if you decide you want ClassB, you only have to change the RHS of the declaration.
I guess if you are enumerating through a collection you can also just to 'var' and then figure out the type later.
Is that it?? Is there some other huge benefit my feeble mind does not see?
It's mostly syntactic sugar. It's really your preference. Unless when using anonymous types, then using var is required. I prefer implicit typing wherever possible though, it really shines with LINQ.
I find it redundant to type out a type twice.
List<string> Foo = new List<string>();
When I can easily just type var when it's obvious what the type is.
var Foo = new List<string>();
var is useful for anonymous types, which do not have names for you to use.
var point = new {X = 10, Y = 10};
This will create an anonymous type with properties X and Y. It's primarily used to support LINQ though. Suppose you have:
class Person
{
public String Name {get; set;}
public Int32 Age {get; set;}
public String Address {get; set;}
// Many other fields
}
List<Person> people; // Some list of people
Now suppose I want to select only the names and years until age 18 of those people who are under the age of 18:
var minors = from person in people where person.Age < 18 select new {Name = person.Name, YearsLeft = 18 - person.Age};
Now minors contains a List of some anonymous type. We can iterate those people with:
foreach (var minor in minors)
{
Console.WriteLine("{0} is {1} years away from age 18!", minor.Name, minor.YearsLeft);
}
None of this would otherwise be possible; we would need to select the whole Person object and then calculate YearsLeft in our loop, which isn't what we want.
I started what turned out to be a hugely controversial thread when I first signed on here (my choice of "evilness" to describe general use of var was obviously a terrible choice.) Needless to say, I have more appreciation for var than I did before I started that thread, as well as a better understanding of how it can be usefully used:
The evilness of 'var' in C#?
Some good reasons to use var:
Brevity
Reduction of Repetition (DRY)
Reduced refactoring effort
Supports anonymous types (key reason it was added to C#)
Have a look at this questions. Maybe they'll help you decide.
Use of var keyword in C#
https://stackoverflow.com/questions/633474/c-do-you-use-var
It allows me to not repeat myself unnecessary. Consider this:
Dictionary<string, List<int>> dict = new Dictionary<string, List<int>>();
We have a very long typename repeated twice on the same line twice with absolutely no benefit. Furthermore, if you ever need to refactor this, you'll need to update the type twice. Whereas this is just as expressive:
var dict = new Dictionary<string, List<int>>();
There's still no doubt about type of dict here, but the code is shorter, and I would claim that it is easier to read as well.
Actually "var" in C# is used to deal with anonymous type.
Like:
var t = new {number = 10, name = "test"};
The overarching reason for the implicit typing was to support anonymous types, like those produced by LINQ queries. They can also be a big benefit when dealing with complex-typed generics...something like Dictionary<int,List<string>>. That's not too complex, but imagine enumerating...
foreach KeyValuePair<int,List<string>> pair in myDictionary
{
}
is simplified with implicit typing.
While the var keyword was primarily introduced to support anonymous types, the main argument I've seen for using it more widely is for brevity/more readable code, plus fitting more on your line of code:
Dictionary<string, double> data = new Dictionary<string, double>();
versus
var data = new Dictionary<string, double>();
Though not a good reason for most people, I also like the var keyword as a blind programmer, as I listen to the code being read out and thus here the variable name after just one syllabul :-)
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.
I have an arraylist that contains items called Room. Each Room has a roomtype such as kitchen, reception etc.
I want to check the arraylist to see if any rooms of that type exist before adding it to the list.
Can anyone recommend a neat way of doing this without the need for multiple foreach loops?
(.NET 2.0)
I havent got access to the linq technology as am running on .net 2.0. I should have stated that in the question.
Apologies
I would not use ArrayList here; since you have .NET 2.0, use List<T> and all becomes simple:
List<Room> rooms = ...
string roomType = "lounge";
bool exists = rooms.Exists(delegate(Room room) { return room.Type == roomType; });
Or with C# 3.0 (still targetting .NET 2.0)
bool exists = rooms.Exists(room => room.Type == roomType);
Or with C# 3.0 and either LINQBridge or .NET 3.5:
bool exists = rooms.Any(room => room.Type == roomType);
(the Any usage will work with more types, not just List<T>)
if (!rooms.Any (r => r.RoomType == typeToFind /*kitchen, ...*/))
//add it or whatever
From your question it's not 100% clear to me if you want to enforce the rule that there may be only one room of a given type, or if you simply want to know.
If you have the invariant that no collection of Rooms may have more than one of the same Room type, you might try using a Dictionary<Type, Room>.
This has the benefit of not performing a linear search on add.
You would add a room using the following operations:
if(rooms.ContainsKey(room.GetType()))
{
// Can't add a second room of the same type
...
}
else
{
rooms.Add(room.GetType(), room);
}
Without using lambda expressions:
void AddRoom(Room r, IList<Room> rooms, IDictionary<string, bool> roomTypes)
{
if (!roomTypes.Contains(r.RoomType))
{
rooms.Add(r);
roomTypes.Add(r.RoomType, true);
}
}
It doesn't actually matter what the type of the value in the dictionary is, because the only thing you're ever looking at is the keys.
Another way is to sort the array, then walk the elements until you find a pair of adjacent duplicates. Make it to the end, and the array is dupe-free.
I thought using lists and doing Exists where an operation that takes O(n) time.
Using Dictionary instead is O(1) and is preferred if memory is not a problem.
If you do not need the sequential List I would try using a Dictionary like this:
Dictionary<Type, List<Room>> rooms = new Dictionary<Type, List<Room>>;
void Main(){
KitchenRoom kr = new KitchenRoom();
DummyRoom dr = new DummyRoom();
RoomType1 rt1 = new RoomType1();
...
AddRoom(kr);
AddRoom(dr);
AddRoom(rt1);
...
}
void AddRoom(Room r){
Type roomtype = r.GetType();
if(!rooms.ContainsKey(roomtype){ //If the type is new, then add it with an empty list
rooms.Add(roomtype, new List<Room>);
}
//And of course add the room.
rooms[roomtype].Add(r);
}
You basically have a list of different roomtypes. But this solution is only OK if you don't need the arraylist. But for large lists this will be the fastest one.
I had a solution once with List<string> with 300.000+ items. Comparing each element with another list of almost the same size took humongous 12hrs to do. Switched the logic to using Dictionary instead and down to 12 minutes. For larger lists I always go Dictionary<mytype, bool> where bool is just a dummy not being used.