Geeks With Blogs
Josh Reuben
 
in and between operators
if (x in (1, 2, 3)) 
if (x in 1:5)
if (x between(1,5))
·        Like Python - Without having to use extension methods
Data Structure Improvements
·        Make BCL collections to be generic: all this ControlCollection, XmlAttributeCollection, SqlErrorCollection, StringCollection becomes Collection<Control>, Collection<XmlAttribute> and Collection<SqlError>
·        Tuple Packing and Unpacking - Like python:
public Tuple<string, int, double> ReturnMyTuple() 
    return "Hello World!", 42, 4.2; 
 
// elsewhere: item1 is a string, item2 is an int, item3 is a double.  
var item1, item2, item3 = ReturnMyTuple(); 
·        yield foreach
·        AddRange support in read-only collection initializers
switch syntax
·        smart case expressions - When the case is an integer, allow lists, ranges and expressions:
    switch (anInt) 
    { 
        case 1, 2:  
            Console.WriteLine("1 or 2"); 
            break; 
        case 3..9
            Console.WriteLine("3 to 9"); 
            break; 
        case >= 10
            Console.WriteLine("10 or higher"); 
            break; 
        default: 
            ... 
    } 
·        And for any other type, still allow the list syntax:
    switch (aString) 
    { 
        case "one", "two": 
            Console.WriteLine("1 or 2"); 
            break; 
        case "three": 
            Console.WriteLine("3"); 
            break; 
        default: 
            ... 
    } 
·        allow expressions that access members of the switched variable:
    switch (aString) 
    { 
        case .IsNullOrEmpty(): 
            ... 
        case .Length > 100: 
            ... 
        case .Contains("foo"): 
            ... 
     } 
 
Null safety
·        ! non-nullable operator
Void DoX(MyClass! obj) { … }
// The following would make the compiler say: "Cannot convert string to string!, an explicit conversion exists
string! nonNullable = someFunctionThatReturnsAString(); 
non-nullable Delegates wont have to be checked for null before they can be called:
DelegateType! DelegateVar;
·        ?. Null Safe Member Operator
// Instead of doing:
var obj = Foo(); 
Bar value = null; 
if(obj.Bar != null && obj.Bar.Something != null) 
  value = obj.Bar.Something.DoSomething(); 
//You can do this with Groovy's null safe member operator ?.
var obj = Foo(); 
var value = obj?.Bar?.Something?.DoSomething(); 
·        ??? Null object chain coalescence operator - null-proof property traversal, like ?(a.B.C) returns null if a is null.
MyClass value=null; 
int something=value.x.y ??? 0;
//something is now 0 
·        IfNull and IfNotNull keywords – more compact, handle short-circuiting 
// instead of
if (a != null && a.SomeProperty != null  && a.SomeProperty.SomeField != null). 
// do this:
IfNotNull(a.SomeProperty.SomeField)  
Extension properties
var value = someObject.Value(); 
someObject.Value(newValue); 
 
More Generics constraints
·        Arithmetic type constraints:
public T Foo<T>(T blah) where T : number { 
  return blah * blah; 
·        generic type restriction on Enum types:
public void DoSomething<T>(T enum) where T: System.Enum { ... } 
·        Operator Constraints: This would even work for your own types, like vectors or matrices, or even DateTime and string
public static int Sum<T>(IEnumerable<T> seq) where T : operator(T=T+T){ .. } 
·        Constructor Signature Constraints
where new(int, string)
·        T? for reference types - Currently it's not possible to write generic code using null values that works with both value and reference types. "T?" is only allowed when T is constrained to be a value type.
·        Ability to invoke static method on the generic parameter
public T Create<T>() where T : static Create() 
     return T.Create(); 
·        delegate constraints
·        way to specify generic constraints on operators
·        specific class and interface constraints
Derive from T:
class Foo<T> : T where T : class 
Constraint for interfaces:
class Foo<T> where T : interface 
Automatic property enhancements
·        Initial values
public string Name { get; set; } = "(NA)"; 
·        read-only values: SomeValue could only be assigned in the constructor, and the C# compiler would need to generate a direct field access (behind the scenes) so that the CLR could tell that an init only field was being used correctly.
public int SomeValue { get; private readonly set; } 
 
 
Expanded Support for Dynamic
·        - like Javascript
·        Dynamic typing - Remove the need for reflection for getting late binding capabilities:
Currently, this would take:
var obj = new Foo(); 
object temp = obj 
           .GetType() 
           .GetProperty(aVariable) 
           .GetValue(obj, null); 
 
int value = (int)temp           
            .GetType() 
            .GetMethod("Method") 
            .Invoke(temp, null); 
What we want:
dynamic obj = new Foo(); 
int value = obj[aVariable].Method(); 
 
·        dynamic object literals – currently anonymous types generate a class with read only properties – need to use reflection to change:
new { Foo = 1, Bar = "string"};
Instead of:
var dict = new Dictionary<string, object> 
  { "Foo", 1 }, 
  { "Bar", "string" } 
}; 
 
dict["Foo"] = 2; 
dict["NewProperty"] = Something(); 
dict["Bar"] = "a new value"; 
 
// I would like to see:
var obj = new dynamic 
  Foo = 1,  
  Bar = "string" 
}; 
 
obj.Foo = 2; 
obj.NewProperty = Something(); 
obj["Bar"] = "a new value"; 
 
Immutable Types
·        Currently, one way to do immutability is to use a wrapper like ReadOnlyCollection<T> and wrap an ICollection<T> with it. And much like Nullable<T> (?) is a wrapper around a value type to support "null" values, Immutable<T> (#) could be a wrapper around types whose values must not change. Sometimes I use Tuple, but its verbose
class Foo 
  public int ID { get; set; } 
  public string Name { get; set; } 
 
.. 
 
private Foo# _member; 
 
public Foo# Something 
  get   {     return _member;   } 
 
Nested Iterators for recursive structures
·        a more efficient and simpler way to iterate over recursive structures:
public override IEnumerable<int> Foo() 
  yield return 1; 
  yield return 2; 
  foreach(var i in base.Foo()) yield i; 
allowing me to write:
public override IEnumerable<int> Foo() 
  yield return 1; 
  yield return 2; 
  yield return base.Foo(); 
}
discriminated unions and pattern matching
·        Like F#
·        Discriminating unions - make message passing easier.
public union Message 
    Get<int, Channel>, 
    Put<int, MyClass>, 
    Delete<int> 
·        then we need pattern matching.
match (message) 
    Get(id, channel): 
    { 
        // ... 
    } 
    Put(id, value): 
    { 
        // ... 
    } 
    Delete(id): 
    { 
        // ... 
    } 
 
Attributes
·        lambda-expressions as attribute parameters
·        generic attributes
·        Make attributes first class citizens by allowing any type of parameter type.
[SomeCoolAttribute(s=>s.Foo)] 
public string MyProp { get; set; }
Enums
·        ToDictionary<Tk,Tv> and ToList operators
·        Typed Enums - Allow any enum to have its own type such as string, float, (object?).
Enum<String>  Options
    Option1 = "xxx" 
    Option2 = "yyy" 
 
property change notification
public Notifyable<int> Foo { get; set; } 
static methods
·        Static extension methods
·        Static abstract / virtual methods
·         
Reference paths
·        The ability to optionally put an "actual path" rather than just a "hint path" into an Assembly reference, so the compiler uses the exact file specified and simply gives an error if it can't be found
·        Static linking of assemblies. i.e. ILMerge but built into the linker so you just tick "statically link" in the reference properties to have the referenced code bundled into your .exe/.dll.
·        The ability to change an assembly reference and have it ask if I want all references to that assembly in my Solution updated to the same one. Upgrading to a new verison of a 3rd party dll when you have 90 projects is no fun (even with a global search & replace on csproj files)
·        The ability to add a Project-reference to a Project that is not in the current Solution (i.e. refer to our libraries via their Projects rather than their output DLL files).
·        The abilty to reference a DEBUG build of an assembly in DEBUG builds, and a RELEASE build of the assembly in RELEASE builds. If you have any debug-only code, being forced to reference only one copy of the dll for all builds is really problematic. Microsoft assumes you will just put all your projects in a single Solution, but when you have hundreds of projects, you'll find that waiting 10 minutes for a build even if you only change a single line of code makes this approach a non-starter.
·        When an application runs and it fails to load an Assembly, it could report the name of the assembly it can't load in the exception instead of "The requested module can't be found".
 
AOP
·        The ability to use attributes to dynamically rewrite the SIL at compile time, like postsharp -  add common functionality to methods, classes, etc. Currently have the following options: 1) place code calls into all methods (not good); 2) use third-party tools to do post-compilation IL rewriting (e.g. PostSharp) or 3) runtime proxying and interception (e.g. Policy Injection Application Block, Castle DynamicProxy). Having compile-type aspects would allow this to be done in a type-safe way checked and optimized by the compiler. Conjecture: This may be part of the upcoming compiler-as-a-service feature.
 
Exception grouping
·        to avoid duplicating the same handling logic
try 
catch (ArgumentOutOfRangeException) 
catch (ArgumentNullException) 
   // Catch a ArgumentOutOfRangeException or a ArgumentNullException 
 
 
CsharpRepl
·        allow the C# compiler to infer a default class, default Main entry point method, and common namespaces (System, etc.). like mono-project.com/CsharpRepl.
// Instead of:
using System; 
 
class Program 
    static void Main(string[] args) 
    { 
        Console.WriteLine(fact(10)); 
        Console.ReadLine(); 
    } 
 
    static int fact(int n) 
    { 
        if (n == 0) 
            return 1; 
        else 
            return n * fact(n - 1); 
    } 
 
// Use this:
static int fact(int n) 
    if (n == 0) 
        return 1; 
    else 
        return n * fact(n - 1); 
 
Console.WriteLine(fact(10)); 
Console.ReadLine(); 
Events
·        Fire keyword for events - The Fire keyword triggers an event only if the event has subscribers
// Instead of:
    // copy ref to delegate for thread safety 
    var evt = this.ApplicationTextUpdated; 
    if (evt != null) 
        evt(this, new EventArgs<string>(applicationText)); 
 
// do this
    Fire(this.ApplicationTextUpdated(this, new EventArgs<string>(applicationText)); 
·        First-class events to expose Observables - cleanly expose an event for subscribing or unsubscribing from the function.
// instead of
Observable.FromEvent<MouseEventArgs>(tree, "MouseMove"); 
// could write
Observable.FromEvent(tree.MouseMove); 
Enhanced numeric support
·        A descent math library – like NMath
·        optimized Vector and Matrix types - Sick of creating these again and again
·        Numeric literal suffixes for all numeric types
o   Currently the following suffixes exist : 1 (no suffix) : int or double (based on decimal separator), 1U : uint, 1L : long, 1UL : ulong, 1f : float, 1d : double, 1m : decimal,
o   For other numeric types, you have to cast explicitly : (byte)1, (sbyte)1, (short)1, (ushort)1
o   have the following suffixes added : 1B : byte, 1SB : sbyte, 1S : short, 1US : ushort, BI: BingInteger, BR: BigReal
OOP / Interface enhancements
·        Duck typing support - Currently need to use 3rd party LinFoo
·        Tuple MustDispose
·        Binding Contracts – specify source object property, target object property
·        Return type based Method Overloading – (big change) method signature take method return type into account.
·        Typedef keyword - as in C++.
·        methodof/propertyof
·        Roles - see traits , what Perl 6 and Moose call roles. Unlike in Scala, roles would need explicit conflict resolution. They're compositional, so it's NOT multiple inheritance
·        make void first class – like F#
·        return "anonymous" types from a method. The only real way to do this currently is to return dynamic and lose static type checking and intellisense.
Posted on Monday, September 13, 2010 1:01 PM NET 5.0 | Back to top


Comments on this post: C# 5.0 - not quite there yet!

# re: C# 5.0 - not quite there yet!
Requesting Gravatar...
Awesome but is this from the Microsoft official announcement?
Left by Shaun on Sep 13, 2010 8:40 PM

# re: C# 5.0 - not quite there yet!
Requesting Gravatar...
switch (aString)
{
case .IsNullOrEmpty():
...
case .Length > 100:
...
case .Contains("foo"):
...
}

That is really strange. What will happen if the string contains "foo" AND the length is >100?

---

public Notifyable<int> Foo { get; set; }

Notify who? How do you add a listener?

---

public int SomeValue { get; private readonly set; }

Isn't it the same as "public int readonly SomeValue"?

---

[SomeCoolAttribute(s=>s.Foo)]
public string MyProp { get; set; }

Attributes parameters should not be evaluated at runtime! Just imagine using reflection... You will not be able to know the exact value of the parameters unless you run the application.
Left by Victor Hurdugaci on Sep 14, 2010 3:00 AM

# re: C# 5.0 - not quite there yet!
Requesting Gravatar...
I like this wish list!

Victor, the notify and the property readonly is to do with WPF. Currently its just a pain in the ass to make notifiable properties. Fields are not the same as properties in that they are invisible to things like WPF, and serializers, so more syntactic sugar would be fantastic to make things a lot more concise.
Left by Keith Nicholas on Sep 14, 2010 8:51 PM

# re: C# 5.0 - not quite there yet!
Requesting Gravatar...
I like a lot of the suggestions you've made, especially the so-called 'smart case expressions' (I never thought I'd miss a feature of vb6!), exception grouping, null safe operator, generic constraints, default property values, and to an extent, typed enums.

I would have to disagree strongly, however, with some of your other suggestions--specifically the dynamic features and natural language keywords (e.g. 'in', and 'between'). This is not to say these features aren't equally beneficial--in fact, your suggestions regarding tuples are perhaps some of the most powerful. I do wonder, however, whether they fit consistently with the established C# paradigms. I suppose what I'm asking is if, rather than heavily altering the standard C# paradigms to match the feature set you desire, you might just be better off trying another language--IronPython, for instance. Of course one can find a way to drive a nail with a saw, but why not just use a hammer instead?

That said, a lockif() keyword would also be a nice addition to simplify double-lock tests. C# already has the lock keyword, so it couldn't be too much more work. And a static destructor would also pair nicely with C#'s present support for static constructors (I ran into a problem recently with unmanaged global hooks, and it certainly would have made my code safer). Apart from your suggestion for 'return type based method overloading' (whose need, I believe, belies a deeper misunderstanding, though you're welcome to disagree), what you have here is a fairly comprehensive, albeit sometimes tendentious, summary of possible improvements to the C# language. Here's to hoping someone of consequence in the project finds this page!
Left by Cameron Behar on Sep 20, 2010 6:37 PM

# re: C# 5.0 - not quite there yet!
Requesting Gravatar...
I mostly agree with Victor. Aside from that, most of the suggested features sound really nice, but don't forget the pythonic << x in "abcd" >>.
I'd love the expression grouping and it seems so easy to implement...
Left by Ozzy on Feb 14, 2011 5:35 PM

# re: C# 5.0 - not quite there yet!
Requesting Gravatar...
I love these ideas. I hope the C# team is listening!

One idea I've been thinking about is taking data binding down to the compiler level. It would be nice to, say, bind properties of objects to one another. Lambda expressions could provide conversion and validation.

For example:

Employee foo = new Employee(...);
Customer bar = new Customer(...);
bind foo.Email : bar.Email; // 2-way binding, both read/write props
oneway foo.Phone : bar.Phone; // 1-way binding to foo

// With conversion
bind foo.Birthday convert (d) => d.ToString() : bar.Email convert (s) => DateTime.Parse(s);

I haven't really thought through very much, yet, but it would be very cool, IMO. I'd love to be able to build my data model and have it just work without writing a big mess of INotifyPropertyChanged and IObservableCollection type of code.

Left by Kevin on Mar 26, 2011 11:24 AM

# re: C# 5.0 - not quite there yet!
Requesting Gravatar...
A lot of the features mentioned are common to many wish-lists including mine. Just one point about the "yield return base.Foo();" - it's ambiguous. The common form for this, which is on the to-implement-eventually list, is "yield foreach base.Foo()", removing the ambiguity.

The problem with yield return automagically foreaching a sequence comes when you try do define a: "public override IEnumerable<IEnumerable> Foo()".

Anyway, I'd also really like to see attributes improved as you say - currently you can't even pass them a decimal, something that causes me some pain.
Left by Alex Davies on Mar 30, 2011 6:26 PM

# re: C# 5.0 - not quite there yet!
Requesting Gravatar...
switch (aString)
{
case .IsNullOrEmpty():
...
case .Length > 100:
...
case .Contains("foo"):
...
}

Nay! switch cases MUST be guaranteed mutually exclusive (so the order you write them does not matter), if not they are just the same as if-else-if statements. If anything, you could be asking for the "elseif" keyword, but really you can already write it "else if", so I don't see the difference.
Left by Gordon Freeman on Aug 12, 2011 12:37 PM

# re: C# 5.0 - not quite there yet!
Requesting Gravatar...
A lot of things to say ..
First for @Alex Davies

If you consider a public iterator that returns IEnumerable<T> (T is what you write in your code, for example int, i am not talking about generic.. but it should be the same), the compiler could easily compute (or think) like this :

if yield return IEnumerable<T> I add myself a foreach,
otherwise (if T it's a "normal" yield)..
i do like before

Now if I take your example (with T = IEnumerable) i do not see any problem...
IEnumerable<IEnumerable> != IEnumerable
Actually in order to this issue appear T should be a recursive type...
IEnumerable<IEnumerable<Ienumerable<...>>>
...that does not exist in C# (as far as i know) :
In that case compiler could not distinguish between IEnumerable<T> and T.

-----


About switch:
I really like the "in", "between", ">=".
The only condition would be that the tested value is a struct type and operator < exist on it (to check all range the user wrote).

I dislike the .IsNullOrEmpty, .Contains("foo") way becasue a switch is for me just an improved-if, by improved, i mean that all cases must are mutually exclusive and compiler is allowed to do some optimisation (like vtable in C++ for example)

--

I dont really like the javascript way. I mean i like javascript a lot but i dont like reflexion because it breaks all type-binding in application (and refactoring for example).
So I like the fact that reflexion is hard to understand... Because of that people dont use it or try to do something else :D
If .Net would make reflexion very writable all (bad) people would start to write code with "var" word, reflexion etc => very bad code.

--

I like a lot the use of "!" because to gain performance and maintainability it's good to indirectly say to next developpers using it (or think myself when i see it) "I (=another developper) use a "string!" type here so this variable should NEVER be null, if something's wrong the error is probably be near the source of data that would ALWAYS return something, please dont correct the line with "if(string.isNullOrEmpty(...))"

--

I like these syntaxes too
MyType elt = a?.b?.c?.elt
and
public int INotifiable<Foo> { get; private readonly set; } = "Neat property!";

==> complex example to know if it makes sense...
I want a property with a default value but i allow an instance to change it only in constructor and i want to notify other classe too, would this syntax work with static class ?

--

An awsome idea (in my opinion) is the new constraint (especially with static method and operator T=T+T... even if i would like static constraint in interface) :
public interface IModule, for example
{
static void StaticConstructorThatInitializesWorstMemoryCase();
}

--


I would like to know if some info are official or not ... It looks like geek wishes :D
Thanks anyway to list all theses wishes !

--

The new official keywords "async" and "await" expected in Framework .Net 5.0 will be awsome because when you try to write a browsing bot you write some callback _everywhere_ :S, it's sometimes difficult to follow the execution flow in this type of application.

Left by Astyan on Oct 07, 2011 5:47 PM

# re: C# 5.0 - not quite there yet!
Requesting Gravatar...
I would like to see in .net 5.0 a kind of extension methods but for classes. For example, I have my own Math static class, and I would like to be able to merge all its methods with System.Math class and use just one Math class in my app.
In the same way it´s usefull to "Util" classes, "Config" classes and all other stuff.
thanks!
Left by Rafael on Dec 25, 2012 7:27 PM

# re: C# 5.0 - not quite there yet!
Requesting Gravatar...
It is significantly important to learn this process as this can be a useful idea. - Morgan Exteriors
Left by Jaime Payne on Dec 29, 2016 8:18 PM

Your comment:
 (will show your gravatar)


Copyright © JoshReuben | Powered by: GeeksWithBlogs.net