.Net 3.5 doesn't support tuples. Too bad, But not sure whether the future version of .net will support tuples or not?
I've just read this article from the MSDN Magazine: Building Tuple
Here are excerpts:
The upcoming 4.0 release of Microsoft
.NET Framework introduces a new type
called System.Tuple. System.Tuple is a
fixed-size collection of
heterogeneously typed data.
Like an array, a tuple has a fixed
size that can't be changed once it has
been created. Unlike an array, each
element in a tuple may be a different
type, and a tuple is able to guarantee
strong typing for each element.
There is already one example of a
tuple floating around the Microsoft
.NET Framework, in the
System.Collections.Generic namespace:
KeyValuePair. While KeyValuePair can be thought of as the same
as Tuple, since they are both
types that hold two things,
KeyValuePair feels different from
Tuple because it evokes a relationship
between the two values it stores (and
with good reason, as it supports the
Dictionary class).
Furthermore, tuples can be arbitrarily
sized, whereas KeyValuePair holds only
two things: a key and a value.
While some languages like F# have special syntax for tuples, you can use the new common tuple type from any language. Revisiting the first example, we can see that while useful, tuples can be overly verbose in languages without syntax for a tuple:
class Program {
static void Main(string[] args) {
Tuple<string, int> t = new Tuple<string, int>("Hello", 4);
PrintStringAndInt(t.Item1, t.Item2);
}
static void PrintStringAndInt(string s, int i) {
Console.WriteLine("{0} {1}", s, i);
}
}
Using the var keyword from C# 3.0, we can remove the type signature on the tuple variable, which allows for somewhat more readable code.
var t = new Tuple<string, int>("Hello", 4);
We've also added some factory methods to a static Tuple class which makes it easier to build tuples in a language that supports type inference, like C#.
var t = Tuple.Create("Hello", 4);
#region tuples
public class Tuple<T>
{
public Tuple(T first)
{
First = first;
}
public T First { get; set; }
}
public class Tuple<T, T2> : Tuple<T>
{
public Tuple(T first, T2 second)
: base(first)
{
Second = second;
}
public T2 Second { get; set; }
}
public class Tuple<T, T2, T3> : Tuple<T, T2>
{
public Tuple(T first, T2 second, T3 third)
: base(first, second)
{
Third = third;
}
public T3 Third { get; set; }
}
public class Tuple<T, T2, T3, T4> : Tuple<T, T2, T3>
{
public Tuple(T first, T2 second, T3 third, T4 fourth)
: base(first, second, third)
{
Fourth = fourth;
}
public T4 Fourth { get; set; }
}
#endregion
And to make declarations prettier:
public static class Tuple
{
//Allows Tuple.New(1, "2") instead of new Tuple<int, string>(1, "2")
public static Tuple<T1, T2> New<T1, T2>(T1 t1, T2 t2)
{
return new Tuple<T1, T2>(t1, t2);
}
//etc...
}
There is a proper (not quick) C# Tuple implementation in Lokad Shared Libraries (Open-source, of course) that includes following required features:
2-5 immutable tuple implementations
Proper DebuggerDisplayAttribute
Proper hashing and equality checks
Helpers for generating tuples from the provided parameters (generics are inferred by compiler) and extensions for collection-based operations.
production-tested.
Implementing Tuple classes or reusing F# classes within C# is only half the story - these give you the ability to create tuples with relative ease, but not really the syntactic sugar which makes them so nice to use in languages like F#.
For example in F# you can use pattern matching to extract both parts of a tuple within a let statment, eg
let (a, b) = someTupleFunc
Unfortunately to do the same using the F# classes from C# would be much less elegant:
Tuple<int,int> x = someTupleFunc();
int a = x.get_Item1();
int b = x.get_Item2();
Tuples represent a powerful method for returning multiple values from a function call without the need to litter your code with throwaway classes, or resorting to ugly ref or out parameters. However, in my opinion, without some syntactic sugar to make their creation and access more elegant, they are of limited use.
In my opinion, the anonymous types feature is not a tuple, but a very similar construct. The output of some LINQ Queries are collections of anonymous types, which behave like tuples.
Here is a statement, which creates a typed tuple :-) on the fly:
var p1 = new {a = "A", b = 3};
see: http://www.developer.com/net/csharp/article.php/3589916
C# 7 supports tuples natively:
var unnamedTuple = ("Peter", 29);
var namedTuple = (Name: "Peter", Age: 29);
(string Name, double Age) typedTuple = ("Peter", 29);
My open source .NET Sasa library has had tuples for years (along with plenty of other functionality, like full MIME parsing). I've been using it in production code for a good few years now.
C# supports simple tuples via generics quite easily (as per an earlier answer), and with "mumble typing" (one of many possible C# language enhancements) to improve type inference they could be very, very powerful.
For what it is worth, F# supports tuples natively, and having played with it, I'm not sure that (anonymous) tuples add much... what you gain in brevity you lose very quickly in code clarity.
For code within a single method, there are anonymous types; for code going outside of a method, I think I'll stick to simple named types. Of course, if a future C# makes it easier to make these immutable (while still easy to work with) I'll be happy.
Here's my set of tuples, they're autogenerated by a Python script, so I've perhaps gone a bit overboard:
Link to Subversion repository
You'll need a username/password, they're both guest
They are based on inheritance, but Tuple<Int32,String> will not compare equal to Tuple<Int32,String,Boolean> even if they happen to have the same values for the two first members.
They also implement GetHashCode and ToString and so forth, and lots of smallish helper methods.
Example of usage:
Tuple<Int32, String> t1 = new Tuple<Int32, String>(10, "a");
Tuple<Int32, String, Boolean> t2 = new Tuple<Int32, String, Boolean>(10, "a", true);
if (t1.Equals(t2))
Console.Out.WriteLine(t1 + " == " + t2);
else
Console.Out.WriteLine(t1 + " != " + t2);
Will output:
10, a != 10, a, True
If I remember my Computer Science classes correctly tuples are just data.
If you want grouped data - create classes that contain properties.
If you need something like the KeyValuePair then there it is.
I'd be surprised - C# is a strongly-typed language, whereas tuples are suited for more dynamically typed languages. C# has been drifting more dynamic as time goes on, but that's syntactic sugar, not a real shift in the underlying data types.
If you want two values in one instance, a KeyValuePair<> is a decent substitute, albeit clumsy. You can also make a struct or a class that'll do the same thing, and is expandable.
To make these useful in a hashtable or dictionary, you will likely want to provide overloads for GetHashCode and Equals.
Related
I decompiled some C# 7 libraries and saw ValueTuple generics being used. What are ValueTuples and why not Tuple instead?
https://learn.microsoft.com/en-gb/dotnet/api/system.tuple
https://learn.microsoft.com/en-gb/dotnet/api/system.valuetuple
What are ValueTuples and why not Tuple instead?
A ValueTuple is a struct which reflects a tuple, same as the original System.Tuple class.
The main difference between Tuple and ValueTuple are:
System.ValueTuple is a value type (struct), while System.Tuple is a reference type (class). This is meaningful when talking about allocations and GC pressure.
System.ValueTuple isn't only a struct, it's a mutable one, and one has to be careful when using them as such. Think what happens when a class holds a System.ValueTuple as a field.
System.ValueTuple exposes its items via fields instead of properties.
Until C# 7, using tuples wasn't very convenient. Their field names are Item1, Item2, etc, and the language hadn't supplied syntax sugar for them like most other languages do (Python, Scala).
When the .NET language design team decided to incorporate tuples and add syntax sugar to them at the language level an important factor was performance. With ValueTuple being a value type, you can avoid GC pressure when using them because (as an implementation detail) they'll be allocated on the stack.
Additionally, a struct gets automatic (shallow) equality semantics by the runtime, where a class doesn't. Although the design team made sure there will be an even more optimized equality for tuples, hence implemented a custom equality for it.
Here is a paragraph from the design notes of Tuples:
Struct or Class:
As mentioned, I propose to make tuple types structs rather than
classes, so that no allocation penalty is associated with them. They
should be as lightweight as possible.
Arguably, structs can end up being more costly, because assignment
copies a bigger value. So if they are assigned a lot more than they
are created, then structs would be a bad choice.
In their very motivation, though, tuples are ephemeral. You would use
them when the parts are more important than the whole. So the common
pattern would be to construct, return and immediately deconstruct
them. In this situation structs are clearly preferable.
Structs also have a number of other benefits, which will become
obvious in the following.
Examples:
You can easily see that working with System.Tuple becomes ambiguous very quickly. For example, say we have a method which calculates a sum and a count of a List<Int>:
public Tuple<int, int> DoStuff(IEnumerable<int> values)
{
var sum = 0;
var count = 0;
foreach (var value in values) { sum += value; count++; }
return new Tuple(sum, count);
}
On the receiving end, we end up with:
Tuple<int, int> result = DoStuff(Enumerable.Range(0, 10));
// What is Item1 and what is Item2?
// Which one is the sum and which is the count?
Console.WriteLine(result.Item1);
Console.WriteLine(result.Item2);
The way you can deconstruct value tuples into named arguments is the real power of the feature:
public (int sum, int count) DoStuff(IEnumerable<int> values)
{
var res = (sum: 0, count: 0);
foreach (var value in values) { res.sum += value; res.count++; }
return res;
}
And on the receiving end:
var result = DoStuff(Enumerable.Range(0, 10));
Console.WriteLine($"Sum: {result.sum}, Count: {result.count}");
Or:
var (sum, count) = DoStuff(Enumerable.Range(0, 10));
Console.WriteLine($"Sum: {sum}, Count: {count}");
Compiler goodies:
If we look under the cover of our previous example, we can see exactly how the compiler is interpreting ValueTuple when we ask it to deconstruct:
[return: TupleElementNames(new string[] {
"sum",
"count"
})]
public ValueTuple<int, int> DoStuff(IEnumerable<int> values)
{
ValueTuple<int, int> result;
result..ctor(0, 0);
foreach (int current in values)
{
result.Item1 += current;
result.Item2++;
}
return result;
}
public void Foo()
{
ValueTuple<int, int> expr_0E = this.DoStuff(Enumerable.Range(0, 10));
int item = expr_0E.Item1;
int arg_1A_0 = expr_0E.Item2;
}
Internally, the compiled code utilizes Item1 and Item2, but all of this is abstracted away from us since we work with a decomposed tuple. A tuple with named arguments gets annotated with the TupleElementNamesAttribute. If we use a single fresh variable instead of decomposing, we get:
public void Foo()
{
ValueTuple<int, int> valueTuple = this.DoStuff(Enumerable.Range(0, 10));
Console.WriteLine(string.Format("Sum: {0}, Count: {1})", valueTuple.Item1, valueTuple.Item2));
}
Note that the compiler still has to make some magic happen (via the attribute) when we debug our application, as it would be odd to see Item1, Item2.
The difference between Tuple and ValueTuple is that Tuple is a reference type and ValueTuple is a value type. The latter is desirable because changes to the language in C# 7 have tuples being used much more frequently, but allocating a new object on the heap for every tuple is a performance concern, particularly when it's unnecessary.
However, in C# 7, the idea is that you never have to explicitly use either type because of the syntax sugar being added for tuple use. For example, in C# 6, if you wanted to use a tuple to return a value, you would have to do the following:
public Tuple<string, int> GetValues()
{
// ...
return new Tuple(stringVal, intVal);
}
var value = GetValues();
string s = value.Item1;
However, in C# 7, you can use this:
public (string, int) GetValues()
{
// ...
return (stringVal, intVal);
}
var value = GetValues();
string s = value.Item1;
You can even go a step further and give the values names:
public (string S, int I) GetValues()
{
// ...
return (stringVal, intVal);
}
var value = GetValues();
string s = value.S;
... Or deconstruct the tuple entirely:
public (string S, int I) GetValues()
{
// ...
return (stringVal, intVal);
}
var (S, I) = GetValues();
string s = S;
Tuples weren't often used in C# pre-7 because they were cumbersome and verbose, and only really used in cases where building a data class/struct for just a single instance of work would be more trouble than it was worth. But in C# 7, tuples have language-level support now, so using them is much cleaner and more useful.
I looked at the source for both Tuple and ValueTuple. The difference is that Tuple is a class and ValueTuple is a struct that implements IEquatable.
That means that Tuple == Tuple will return false if they are not the same instance, but ValueTuple == ValueTuple will return true if they are of the same type and Equals returns true for each of the values they contain.
In addition to the comments above, one unfortunate gotcha of ValueTuple is that, as a value type, the named arguments get erased when compiled to IL, so they're not available for serialisation at runtime.
i.e. Your sweet named arguments will still end up as "Item1", "Item2", etc. when serialised via e.g. Json.NET.
Other answers forgot to mention important points.Instead of rephrasing, I'm gonna reference the XML documentation from source code:
The ValueTuple types (from arity 0 to 8) comprise the runtime implementation that underlies
tuples in C# and struct tuples in F#.
Aside from created via language syntax, they are most easily created via the
ValueTuple.Create factory methods.
The System.ValueTuple types differ from the System.Tuple types in that:
they are structs rather than classes,
they are mutable rather than readonly, and
their members (such as Item1, Item2, etc) are fields rather than properties.
With introduction of this type and C# 7.0 compiler, you can easily write
(int, string) idAndName = (1, "John");
And return two values from a method:
private (int, string) GetIdAndName()
{
//.....
return (id, name);
}
Contrary to System.Tuple you can update its members (Mutable) because they are public read-write Fields that can be given meaningful names:
(int id, string name) idAndName = (1, "John");
idAndName.name = "New Name";
Late-joining to add a quick clarification on these two factoids:
they are structs rather than classes
they are mutable rather than readonly
One would think that changing value-tuples en-masse would be straightforward:
foreach (var x in listOfValueTuples) { x.Foo = 103; } // wont even compile because x is a value (struct) not a variable
var d = listOfValueTuples[0].Foo;
Someone might try to workaround this like so:
// initially *.Foo = 10 for all items
listOfValueTuples.Select(x => x.Foo = 103);
var d = listOfValueTuples[0].Foo; // 'd' should be 103 right? wrong! it is '10'
The reason for this quirky behavior is that the value-tuples are exactly value-based (structs) and thus the .Select(...) call works on cloned-structs rather than on the originals. To resolve this we must resort to:
// initially *.Foo = 10 for all items
listOfValueTuples = listOfValueTuples
.Select(x => {
x.Foo = 103;
return x;
})
.ToList();
var d = listOfValueTuples[0].Foo; // 'd' is now 103 indeed
Alternatively of course one might try the straightforward approach:
for (var i = 0; i < listOfValueTuples.Length; i++) {
listOfValueTuples[i].Foo = 103; //this works just fine
// another alternative approach:
//
// var x = listOfValueTuples[i];
// x.Foo = 103;
// listOfValueTuples[i] = x; //<-- vital for this alternative approach to work if you omit this changes wont be saved to the original list
}
var d = listOfValueTuples[0].Foo; // 'd' is now 103 indeed
Hope this helps someone struggling to make heads of tails out of list-hosted value-tuples.
First, I don't have much experience in .Net - especially within the last 7 years.
I'm trying to develop an application and would to incorporate another library (https://github.com/Giorgi/Math-Expression-Evaluator)
That library allows me to evaluate math expressions like Evaluate("a+b", a: 1,b: 1). The method signature is public decimal Evaluate(string expression, object argument = null)
I would like to understand better how .Net translates comma-separated arguments into a single "argument".
I'm not sure how to create that argument dynamically.. for example, iterating through a list of values and creating an object that will match the appropriate argument for that signature.
I'm really just looking for pointers for documentation and more information.. Thanks for anything.
EDIT: Sorry.. purposely left it broad because I wasn't looking for people to do my work for me.. just can't seem to find a starting point to do my own research.
The method is called like
dynamic engine = new ExpressionEvaluator() ;
engine.Evaluate("(c+b)*a", a: 6, b: 4.5, c: 2.6)) ;
In the body of Evalute() is this code (which turns that argument into a Dictionary of String, Decimal pairs.
if (argument == null)
{
return new Dictionary<string, decimal>();
}
var argumentType = argument.GetType();
var properties = argumentType.GetProperties(BindingFlags.Instance | BindingFlags.Public)
.Where(p => p.CanRead && IsNumeric(p.PropertyType));
var arguments = properties.ToDictionary(property => property.Name,
property => Convert.ToDecimal(property.GetValue(argument, null)));
return arguments;
What I'd like to be able to do is parse a String like "a:1,b:2" and turn it into an object that matches that Evaluate() signature.
That library is using high level magic... Very high level :-)
The trick is that the class is declared as:
public class ExpressionEvaluator : DynamicObject
So it is a class that implements the dynamic magic introduced in .NET 4.0
Now... In the class there are two Evaluate methods:
public decimal Evaluate(string expression, object argument = null)
and
private decimal Evaluate(string expression, Dictionary<string, decimal> arguments)
The only method normally visible and usable is the first one. It is used like:
engine.Evaluate("a + b + c", new { a = 1, b = 2, c = 3 });
The new { ... } creates an anonymous object, that is then "unpacked" here through the use of reflection to a Dictionary<string, decimal> to be fed to the private Evaluate().
If you try to use the other notation, the one like:
engine.Evaluate("a + b + c", a: 1, b: 2, c: 3 });
then the .NET can't match the method to the public Evaluate() that is present, but the class, being a subclass of DynamicObject, causes the C# compiler to write some "magic" code that launches this method (that is still implemented by the ExpressionEvaluator):
public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result)
That first checks that we want to call Evaluate:
if (nameof(Evaluate) != binder.Name)
and if we are trying to call Evaluate, it unpacks the parameters to a new Dictionary<string, decimal>() and then calls the private Evaluate().
As a sidenote, to use the "dynamic" way of writing Evaluate you have to declare the engine variable like;
dynamic dynamicEngine = new ExpressionEvaluator();
So using the dynamic variable type.
Now... As the library is written you can:
Use an anonymous object, with the problem that anonymous objects must have their "shape" defined at compile time (so at compile time you must know that you will need a a, a b and a c. You can't need a d at runtime if you didn't create a new { a, b, c, d } at compile time). See for example a response I gave three years ago about how to create dynamic anonymous types at runtime. One of the reasons I gave for that block of code was:
there are parts of the .NET framework that heavily use reflection to render objects (for example all the various datagrids). These parts are incompatible with dynamic objects and often don't support object[]. A solution is often to encapsulate the data in a DataTable... or you can use this :-)
Note that in one of the comments to that response there is a link to a modified version of my code used by one of the many implementations of Dynamic.Linq.
Use a non-anonymous object (a new Foo { a = 1, b = 2 c = 3 }). The library doesn't make distinctions between anonymous and non-anonymous objects. So same limitation as before, because at compile time you need a Foo class with the right number of parameters
Use the dynamic notation. Sadly even that is quite static. You can't easily add new parameters, that for the number and name of the "variables" must be defined at compile time.
A possible solution is to modify the source code (it is a single file) and make public this method:
private decimal Evaluate(string expression, Dictionary<string, decimal> arguments)
then you can easily and dynamically populate the Dictionary<string, decimal> arguments
Is there a functionality for C# 7 ValueTuple similar to Python's slicing? The syntax for value tuples in C# is similar to Python but I can't find an elegant way to get subtuple from tuple for example.
In Python 3:
tuple = (1,2,3)
subtuple = t[:2] #subtuple is (1, 2)
In C# 7:
var tuple = (1,2,3) //Very similar to Python!
var subtuple = (tuple.Item1, tuple.Item2) //Not very elegant, especially for bigger tuples
No, there is nothing like that in C#. Due to the statically-typed nature of C#, a feature like that couldn't work with arbitrary expressions for the slice points.
I think that the closest you can get is to create a bunch of extension methods that have the slice points embedded in their names. E.g.:
public static (T1, T2) Take2<T1, T2, T3>(this (T1, T2, T3) tuple) =>
(tuple.Item1, tuple.Item2);
var tuple = (1,2,3);
var subtuple = tuple.Take2();
Note that if the tuple members have names, this will strip them off.
Often you want to send multiple values but due to low use (i.e. it is only used in one or two places), it's hard to justify creating a new type.
The Tuple<...> and KeyValuePair<,> type are very useful, but there isn't real language support for them.
Well sort of, a nice trick to use for Lists of tuples is to create a type that extends the List and adding a custom add method:
e.g.
public class TupleList<T1,T2> : List<Tuple<T1,T2>>{
public void Add(T1 key, T2 value){
base.Add(Tuple.Create(key, value));
}
}
This means that if I have a method that takes an IEnumerable<Tuple<int,string>>, I can use the following code to quickly build up the list like so::
Foo(new TupleList<int,string>{{1,"one"},{2,"two"},{3,"three"}});
This makes winding values into a tuple list easier as we don't have to constantly keep saying Tuple.Create, and gets us almost to a nice functional languages syntax.
But when working with a tuple it is useful to unwind it out into its different components. This extension method might be useful in this respect::
public static void Unwind<T1,T2>(this Tuple<T1,T2> tuple,out T1 var1,out T2 var2)
{
var1 = tuple.Item1;
var2 = tuple.Item2;
}
But even that's annoying as out parameters are not variant at all. That is if T1 is a string, I can't send in an object variable even though they are assignable, when as I can do the unwinding by hand otherwise. I can't really suggest a reason why you might want this variance, but if its there, I can't see why you would want to lose it.
Anyone have other tips to making working tuples, or tuple like objects easier in C#?
An important potential use for tuples might be generic memoization. Which is very easy in languages like F#, but hard in C#.
I'm currently using Tuples to supply a MethodBase and an array of tokens (constants, objects, or argument tokens), supplied to a dynamicly built object to construct certain member fields.
Since I wanted to make the syntax easier on API consumers, I created Add methods that can take a ConstructorInfo or a MethodInfo and a params array of objects.
Edit:
Eric Lippert as usual has excellent motivation for using Tuples here and he even says what I suspected there really is no support:
What requirement was the tuple designed to solve?
In C# you can alias closed generic types, which Tuple is, this enables you to provide some better insight to what is intended. Doesn't change code much, but if you look at the example below the intent of what GetTemp is returning is better.
Without alias:
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
var result = GetTemp(10, 10);
Console.WriteLine("Temp for {0} is {1}", result.Item2, result.Item1);
}
// You give a lat & a long and you get the closest city & temp for it
static Tuple<double, string> GetTemp(double lat, double #long)
{
// just for example
return Tuple.Create(10d, "Mordor");
}
}
}
With alias:
namespace ConsoleApplication1
{
using CityTemp = Tuple<double, string>;
class Program
{
static void Main(string[] args)
{
var result = GetTemp(10, 10);
Console.WriteLine("Temp for {0} is {1}", result.Item2, result.Item1);
}
// You give a lat & a long and you get the closest city & temp for it
static CityTemp GetTemp(double lat, double #long)
{
// just for example
return new CityTemp(10, "Mordor");
}
}
}
Use Mono! They have experimental support for binding variables to tuple members so you could call a method like
Tuple<string, string, string, int, string> ParseUri (string url);
using code like
(user, password, host, port, path) = ParseUri (url);
There will be an awesome tuple feature coming with c#7 / visual studio 15.
basically you can do soething like that
static (int x, int y) DoSomething()
{
return (1, 2);
}
static void Test()
{
var cool = DoSomething();
var value = cool.x;
}
Read according post
As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 11 years ago.
Locked. This question and its answers are locked because the question is off-topic but has historical significance. It is not currently accepting new answers or interactions.
This came to my mind after I learned the following from this question:
where T : struct
We, C# developers, all know the basics of C#. I mean declarations, conditionals, loops, operators, etc.
Some of us even mastered the stuff like Generics, anonymous types, lambdas, LINQ, ...
But what are the most hidden features or tricks of C# that even C# fans, addicts, experts barely know?
Here are the revealed features so far:
Keywords
yield by Michael Stum
var by Michael Stum
using() statement by kokos
readonly by kokos
as by Mike Stone
as / is by Ed Swangren
as / is (improved) by Rocketpants
default by deathofrats
global:: by pzycoman
using() blocks by AlexCuse
volatile by Jakub Šturc
extern alias by Jakub Šturc
Attributes
DefaultValueAttribute by Michael Stum
ObsoleteAttribute by DannySmurf
DebuggerDisplayAttribute by Stu
DebuggerBrowsable and DebuggerStepThrough by bdukes
ThreadStaticAttribute by marxidad
FlagsAttribute by Martin Clarke
ConditionalAttribute by AndrewBurns
Syntax
?? (coalesce nulls) operator by kokos
Number flaggings by Nick Berardi
where T:new by Lars Mæhlum
Implicit generics by Keith
One-parameter lambdas by Keith
Auto properties by Keith
Namespace aliases by Keith
Verbatim string literals with # by Patrick
enum values by lfoust
#variablenames by marxidad
event operators by marxidad
Format string brackets by Portman
Property accessor accessibility modifiers by xanadont
Conditional (ternary) operator (?:) by JasonS
checked and unchecked operators by Binoj Antony
implicit and explicit operators by Flory
Language Features
Nullable types by Brad Barker
Anonymous types by Keith
__makeref __reftype __refvalue by Judah Himango
Object initializers by lomaxx
Format strings by David in Dakota
Extension Methods by marxidad
partial methods by Jon Erickson
Preprocessor directives by John Asbeck
DEBUG pre-processor directive by Robert Durgin
Operator overloading by SefBkn
Type inferrence by chakrit
Boolean operators taken to next level by Rob Gough
Pass value-type variable as interface without boxing by Roman Boiko
Programmatically determine declared variable type by Roman Boiko
Static Constructors by Chris
Easier-on-the-eyes / condensed ORM-mapping using LINQ by roosteronacid
__arglist by Zac Bowling
Visual Studio Features
Select block of text in editor by Himadri
Snippets by DannySmurf
Framework
TransactionScope by KiwiBastard
DependantTransaction by KiwiBastard
Nullable<T> by IainMH
Mutex by Diago
System.IO.Path by ageektrapped
WeakReference by Juan Manuel
Methods and Properties
String.IsNullOrEmpty() method by KiwiBastard
List.ForEach() method by KiwiBastard
BeginInvoke(), EndInvoke() methods by Will Dean
Nullable<T>.HasValue and Nullable<T>.Value properties by Rismo
GetValueOrDefault method by John Sheehan
Tips & Tricks
Nice method for event handlers by Andreas H.R. Nilsson
Uppercase comparisons by John
Access anonymous types without reflection by dp
A quick way to lazily instantiate collection properties by Will
JavaScript-like anonymous inline-functions by roosteronacid
Other
netmodules by kokos
LINQBridge by Duncan Smart
Parallel Extensions by Joel Coehoorn
This isn't C# per se, but I haven't seen anyone who really uses System.IO.Path.Combine() to the extent that they should. In fact, the whole Path class is really useful, but no one uses it!
I'm willing to bet that every production app has the following code, even though it shouldn't:
string path = dir + "\\" + fileName;
lambdas and type inference are underrated. Lambdas can have multiple statements and they double as a compatible delegate object automatically (just make sure the signature match) as in:
Console.CancelKeyPress +=
(sender, e) => {
Console.WriteLine("CTRL+C detected!\n");
e.Cancel = true;
};
Note that I don't have a new CancellationEventHandler nor do I have to specify types of sender and e, they're inferable from the event. Which is why this is less cumbersome to writing the whole delegate (blah blah) which also requires you to specify types of parameters.
Lambdas don't need to return anything and type inference is extremely powerful in context like this.
And BTW, you can always return Lambdas that make Lambdas in the functional programming sense. For example, here's a lambda that makes a lambda that handles a Button.Click event:
Func<int, int, EventHandler> makeHandler =
(dx, dy) => (sender, e) => {
var btn = (Button) sender;
btn.Top += dy;
btn.Left += dx;
};
btnUp.Click += makeHandler(0, -1);
btnDown.Click += makeHandler(0, 1);
btnLeft.Click += makeHandler(-1, 0);
btnRight.Click += makeHandler(1, 0);
Note the chaining: (dx, dy) => (sender, e) =>
Now that's why I'm happy to have taken the functional programming class :-)
Other than the pointers in C, I think it's the other fundamental thing you should learn :-)
From Rick Strahl:
You can chain the ?? operator so that you can do a bunch of null comparisons.
string result = value1 ?? value2 ?? value3 ?? String.Empty;
Aliased generics:
using ASimpleName = Dictionary<string, Dictionary<string, List<string>>>;
It allows you to use ASimpleName, instead of Dictionary<string, Dictionary<string, List<string>>>.
Use it when you would use the same generic big long complex thing in a lot of places.
From CLR via C#:
When normalizing strings, it is highly
recommended that you use
ToUpperInvariant instead of
ToLowerInvariant because Microsoft has
optimized the code for performing
uppercase comparisons.
I remember one time my coworker always changed strings to uppercase before comparing. I've always wondered why he does that because I feel it's more "natural" to convert to lowercase first. After reading the book now I know why.
My favorite trick is using the null coalesce operator and parentheses to automagically instantiate collections for me.
private IList<Foo> _foo;
public IList<Foo> ListOfFoo
{ get { return _foo ?? (_foo = new List<Foo>()); } }
Avoid checking for null event handlers
Adding an empty delegate to events at declaration, suppressing the need to always check the event for null before calling it is awesome. Example:
public delegate void MyClickHandler(object sender, string myValue);
public event MyClickHandler Click = delegate {}; // add empty delegate!
Let you do this
public void DoSomething()
{
Click(this, "foo");
}
Instead of this
public void DoSomething()
{
// Unnecessary!
MyClickHandler click = Click;
if (click != null) // Unnecessary!
{
click(this, "foo");
}
}
Please also see this related discussion and this blog post by Eric Lippert on this topic (and possible downsides).
Everything else, plus
1) implicit generics (why only on methods and not on classes?)
void GenericMethod<T>( T input ) { ... }
//Infer type, so
GenericMethod<int>(23); //You don't need the <>.
GenericMethod(23); //Is enough.
2) simple lambdas with one parameter:
x => x.ToString() //simplify so many calls
3) anonymous types and initialisers:
//Duck-typed: works with any .Add method.
var colours = new Dictionary<string, string> {
{ "red", "#ff0000" },
{ "green", "#00ff00" },
{ "blue", "#0000ff" }
};
int[] arrayOfInt = { 1, 2, 3, 4, 5 };
Another one:
4) Auto properties can have different scopes:
public int MyId { get; private set; }
Thanks #pzycoman for reminding me:
5) Namespace aliases (not that you're likely to need this particular distinction):
using web = System.Web.UI.WebControls;
using win = System.Windows.Forms;
web::Control aWebControl = new web::Control();
win::Control aFormControl = new win::Control();
I didn't know the "as" keyword for quite a while.
MyClass myObject = (MyClass) obj;
vs
MyClass myObject = obj as MyClass;
The second will return null if obj isn't a MyClass, rather than throw a class cast exception.
Two things I like are Automatic properties so you can collapse your code down even further:
private string _name;
public string Name
{
get
{
return _name;
}
set
{
_name = value;
}
}
becomes
public string Name { get; set;}
Also object initializers:
Employee emp = new Employee();
emp.Name = "John Smith";
emp.StartDate = DateTime.Now();
becomes
Employee emp = new Employee {Name="John Smith", StartDate=DateTime.Now()}
The 'default' keyword in generic types:
T t = default(T);
results in a 'null' if T is a reference type, and 0 if it is an int, false if it is a boolean,
etcetera.
Attributes in general, but most of all DebuggerDisplay. Saves you years.
The # tells the compiler to ignore any
escape characters in a string.
Just wanted to clarify this one... it doesn't tell it to ignore the escape characters, it actually tells the compiler to interpret the string as a literal.
If you have
string s = #"cat
dog
fish"
it will actually print out as (note that it even includes the whitespace used for indentation):
cat
dog
fish
I think one of the most under-appreciated and lesser-known features of C# (.NET 3.5) are Expression Trees, especially when combined with Generics and Lambdas. This is an approach to API creation that newer libraries like NInject and Moq are using.
For example, let's say that I want to register a method with an API and that API needs to get the method name
Given this class:
public class MyClass
{
public void SomeMethod() { /* Do Something */ }
}
Before, it was very common to see developers do this with strings and types (or something else largely string-based):
RegisterMethod(typeof(MyClass), "SomeMethod");
Well, that sucks because of the lack of strong-typing. What if I rename "SomeMethod"? Now, in 3.5 however, I can do this in a strongly-typed fashion:
RegisterMethod<MyClass>(cl => cl.SomeMethod());
In which the RegisterMethod class uses Expression<Action<T>> like this:
void RegisterMethod<T>(Expression<Action<T>> action) where T : class
{
var expression = (action.Body as MethodCallExpression);
if (expression != null)
{
// TODO: Register method
Console.WriteLine(expression.Method.Name);
}
}
This is one big reason that I'm in love with Lambdas and Expression Trees right now.
"yield" would come to my mind. Some of the attributes like [DefaultValue()] are also among my favorites.
The "var" keyword is a bit more known, but that you can use it in .NET 2.0 applications as well (as long as you use the .NET 3.5 compiler and set it to output 2.0 code) does not seem to be known very well.
Edit: kokos, thanks for pointing out the ?? operator, that's indeed really useful. Since it's a bit hard to google for it (as ?? is just ignored), here is the MSDN documentation page for that operator: ?? Operator (C# Reference)
I tend to find that most C# developers don't know about 'nullable' types. Basically, primitives that can have a null value.
double? num1 = null;
double num2 = num1 ?? -100;
Set a nullable double, num1, to null, then set a regular double, num2, to num1 or -100 if num1 was null.
http://msdn.microsoft.com/en-us/library/1t3y8s4s(VS.80).aspx
one more thing about Nullable type:
DateTime? tmp = new DateTime();
tmp = null;
return tmp.ToString();
it is return String.Empty. Check this link for more details
Here are some interesting hidden C# features, in the form of undocumented C# keywords:
__makeref
__reftype
__refvalue
__arglist
These are undocumented C# keywords (even Visual Studio recognizes them!) that were added to for a more efficient boxing/unboxing prior to generics. They work in coordination with the System.TypedReference struct.
There's also __arglist, which is used for variable length parameter lists.
One thing folks don't know much about is System.WeakReference -- a very useful class that keeps track of an object but still allows the garbage collector to collect it.
The most useful "hidden" feature would be the yield return keyword. It's not really hidden, but a lot of folks don't know about it. LINQ is built atop this; it allows for delay-executed queries by generating a state machine under the hood. Raymond Chen recently posted about the internal, gritty details.
Unions (the C++ shared memory kind) in pure, safe C#
Without resorting to unsafe mode and pointers, you can have class members share memory space in a class/struct. Given the following class:
[StructLayout(LayoutKind.Explicit)]
public class A
{
[FieldOffset(0)]
public byte One;
[FieldOffset(1)]
public byte Two;
[FieldOffset(2)]
public byte Three;
[FieldOffset(3)]
public byte Four;
[FieldOffset(0)]
public int Int32;
}
You can modify the values of the byte fields by manipulating the Int32 field and vice-versa. For example, this program:
static void Main(string[] args)
{
A a = new A { Int32 = int.MaxValue };
Console.WriteLine(a.Int32);
Console.WriteLine("{0:X} {1:X} {2:X} {3:X}", a.One, a.Two, a.Three, a.Four);
a.Four = 0;
a.Three = 0;
Console.WriteLine(a.Int32);
}
Outputs this:
2147483647
FF FF FF 7F
65535
just add
using System.Runtime.InteropServices;
Using # for variable names that are keywords.
var #object = new object();
var #string = "";
var #if = IpsoFacto();
If you want to exit your program without calling any finally blocks or finalizers use FailFast:
Environment.FailFast()
Returning anonymous types from a method and accessing members without reflection.
// Useful? probably not.
private void foo()
{
var user = AnonCast(GetUserTuple(), new { Name = default(string), Badges = default(int) });
Console.WriteLine("Name: {0} Badges: {1}", user.Name, user.Badges);
}
object GetUserTuple()
{
return new { Name = "dp", Badges = 5 };
}
// Using the magic of Type Inference...
static T AnonCast<T>(object obj, T t)
{
return (T) obj;
}
Here's a useful one for regular expressions and file paths:
"c:\\program files\\oldway"
#"c:\program file\newway"
The # tells the compiler to ignore any escape characters in a string.
Mixins. Basically, if you want to add a feature to several classes, but cannot use one base class for all of them, get each class to implement an interface (with no members). Then, write an extension method for the interface, i.e.
public static DeepCopy(this IPrototype p) { ... }
Of course, some clarity is sacrificed. But it works!
Not sure why anyone would ever want to use Nullable<bool> though. :-)
True, False, FileNotFound?
This one is not "hidden" so much as it is misnamed.
A lot of attention is paid to the algorithms "map", "reduce", and "filter". What most people don't realize is that .NET 3.5 added all three of these algorithms, but it gave them very SQL-ish names, based on the fact that they're part of LINQ.
"map" => Select Transforms data
from one form into another
"reduce" => Aggregate Aggregates
values into a single result
"filter" => Where Filters data
based on a criteria
The ability to use LINQ to do inline work on collections that used to take iteration and conditionals can be incredibly valuable. It's worth learning how all the LINQ extension methods can help make your code much more compact and maintainable.
Environment.NewLine
for system independent newlines.
If you're trying to use curly brackets inside a String.Format expression...
int foo = 3;
string bar = "blind mice";
String.Format("{{I am in brackets!}} {0} {1}", foo, bar);
//Outputs "{I am in brackets!} 3 blind mice"
?? - coalescing operator
using (statement / directive) - great keyword that can be used for more than just calling Dispose
readonly - should be used more
netmodules - too bad there's no support in Visual Studio
#Ed, I'm a bit reticent about posting this as it's little more than nitpicking. However, I would point out that in your code sample:
MyClass c;
if (obj is MyClass)
c = obj as MyClass
If you're going to use 'is', why follow it up with a safe cast using 'as'? If you've ascertained that obj is indeed MyClass, a bog-standard cast:
c = (MyClass)obj
...is never going to fail.
Similarly, you could just say:
MyClass c = obj as MyClass;
if(c != null)
{
...
}
I don't know enough about .NET's innards to be sure, but my instincts tell me that this would cut a maximum of two type casts operations down to a maximum of one. It's hardly likely to break the processing bank either way; personally, I think the latter form looks cleaner too.
Maybe not an advanced technique, but one I see all the time that drives me crazy:
if (x == 1)
{
x = 2;
}
else
{
x = 3;
}
can be condensed to:
x = (x==1) ? 2 : 3;