C# 5.0 not quite there yet!

原文:
http://geekswithblogs.net/JoshReuben/archive/2010/09/13/c-5.0---not-quite-there-yet.aspx
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 3 rd 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.

你可能感兴趣的:(C# 5.0 not quite there yet!)