Actually, I have no idea... but here are my suggestions for new features that I think are worth it:
1. Generic Operators
Currently, operators do not work on generic types without some base class constraint that defines those operators. For instance, the following code does not compile:
public static T Sum<T>(IEnumerable<T> data) where T : struct {
T sum = new T();
foreach(T i in data)
sum += i;
return sum;
}
The reason is that the compiler and the CLR cannot insure all types have the + operator. This is why constraints were invented.
But there is currently no constraint that pertains to operators. One possible syntax may be something like this:
public static T Sum<T>(IEnumerable<T> data) where T : struct,
T : T operator+(T, T) {
T sum = new T();
foreach(T i in data)
sum += i;
return sum;
}
.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }
but this is awkward (to say the least), as operators can accept any types as arguments, but really unnecessary. The compiler can determine automatically the required constraints based on the usage of the operators themselves. So, the first code snippet should compile and execute fine for any type that implements operator+. What's needed is a way for the compiler and CLR to represent that kind of constraint in the metadata.
2. Generic Specialization
More generic stuff. Currently, a generic type or a generic method cannot be specialized for a specific type. For example, the List<T> class cannot be specialized for (say) List<string> to behave differently, perhaps with string based optimizations or whatever. This is possible in C++ but not in C# (probably because the metadata and CLR do not support this). This could be a nice feature.
3. Multiple Inheritance
Yes, I know the CLR does not support inheriting from multiple types, and for a good reason. Multiple inheritance can create great problems, as evident in C++ (for example) that does support it. Just look at virtual inheritance in C++ and you'll understand why...
I'm not suggesting adding this to the CLR. But multiple inheritance in its simplest form can be implemented by containment and delegation:
class SomeBase { /*...*/ }
class A {
public void Foo() {
/*...*/
}
}
class B : SomeBase { // normal inheritance
private A _a = new A();
public void Foo() {
_a.Foo();
}
public static implicit operator A(B b) {
return b._a;
}
}
.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }
void UseB() {
B b = new B();
b.Foo();
A a = b;
a.Foo();
}
This is quite boilerplate, so the compiler can complete this on its own: add a private member of the "inherited" type and automatically delegate, and add an conversion operator. Here's a new suggested syntax:
class B : SomeBase, A {
}
.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }
The compiler will insert all the other stuff. The first base specified is the "real" base class.
4. Auto-implemented Interfaces
Sometimes a type implements an interface by delegating it to a member that implements it. For example:
class A : ICollection<string> {
private readonly List<string> list = new List<string>();
#region ICollection<string> Members
public void Add(string item) {
list.Add(item);
}
public void Clear() {
list.Clear();
}
public bool Contains(string item) {
return list.Contains(item);
}
public void CopyTo(string[] array, int arrayIndex) {
list.CopyTo(array, arrayIndex);
}
public int Count {
get { return list.Count; }
}
public bool Remove(string item) {
return list.Remove(item);
}
public bool IsReadOnly {
get { return ((ICollection<String>)list).IsReadOnly; }
}
#endregion
#region IEnumerable<string> Members
public IEnumerator<string> GetEnumerator() {
return list.GetEnumerator();
}
#endregion
#region IEnumerable Members
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() {
return list.GetEnumerator();
}
#endregion
}
.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }
This is pretty straightforward, but tedious. I'd like to see something like:
class A : IEnumerable<string> {
private string List<string> list = new List<string>() : implements IEnumerable<string>;
}
This is my list so far. I may come up with a few more ideas along the way...
.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }