Eric Gunnerson - How do you design new features for C#?
- Posted: Apr 29, 2004 at 2:17 PM
- 27,329 Views
- 14 Comments
Loading User Information from Channel 9
Something went wrong getting user information from Channel 9
Loading User Information from MSDN
Something went wrong getting user information from MSDN
Loading Visual Studio Achievements
Something went wrong getting the Visual Studio Achievements
Right click “Save as…”
Comments have been closed since this content was published more than 30 days ago, but if you'd like to continue the conversation,
please create a new thread in our Forums,
or
Contact Us and let us know.
Follow the Discussion
Oops, something didn't work.
What does this mean?
Following an item on Channel 9 allows you to watch for new content and comments that you are interested in. You need to be signed in to Channel 9 to use this feature.What does this mean?
Following an item on Channel 9 allows you to watch for new content and comments that you are interested in and view them all on your notifications page.sign up for email notifications?
First of all C# rocks!!!
My question is about optional parameters in C#, or there lack of. VB.NET & CLR has support for them, but not C#. I have been hoping that C# 2.0 (Whidbey) will include support for optional parameters, but it seems that it will not.
What is the reasoning for not including optional parameters (aka default parameters) support with C#?
eg...
public void MyMethod(int num, string text = “default text”)
{
...
}
cheers,
Mike M
WinInsider.com
I think I've seen the reasoning for this from other languages (Java I believe). THe reason I recall is that you can handle optional parameters with method overloading and this also alleviates some ambiguity problems as well.
eg.
public void MyMethod(int num) {
MyMethod(num, "default text");
}
public void MyMethod(int num, string text = “default text”)
{
...
}
That said, the lack of optional params in C# becomes a REAL issue when automating any Office apps via Interop, where masses of optional params are very common.
Come to think of it, COM Interop on Office applications is so nasty I tend to stay far away at the best of times.
This would be useful if the catcher can handle and fix/resolve the cause of the exception and then "reverse throw" the exception back where it was thrown and continue as if the exception never had happened.
Such a feature would be handy in C# as well, I guess
Check out this article where Anders Hejlsberg discusses the pros and cons of checked exceptions:
http://www.artima.com/intv/handcuffs.html
Charles
Or am I wrong?
You are not wrong. In Java you can define which exceptions a method will throw by using the throws keyword. Consumers will know ahead of time which exceptions to catch. Anders explains the shortcomings of this pattern in the article I mentioned above.
You seem to be interested in exceptions. This is good
What do you think of the exception model currently in place in the Framework?
Charles
So these "checked exceptions" and your decision to avoid them is a good thing, I guess. But this would not make my original suggestion unusable, if I'm understanding correctly...
I do like exceptions, correct
In detail, I have problems to get the call stack information of the original thrown exception when installing a global exception handler in a C# application by implementing an UnhandledExceptionEventHandler and a ThreadExceptionEventHandler. Never been able to get this working correctly. Probably it is my fault, but since you are already asking, the Framework could help me more on this issue to avoid the mistakes I'm now making
Similar things apply when centrally catching exceptions in ASP.NET applications. But I'm trying to advance and improve!
Thanks for your feedback!
Uwe
If "What features would you like to see the C# team add?" is really mean what it is saying then this is my wish list:
(I have implemented some of these in a library named Foop which is an alpha version)
1 - Define new operators; i.e. an operator named &&&.
2 - Define Generic operators; currently we can just overload the existing operators and if the operands are going to be Generic, they can only be of type of one of the Type Parameters of the container class.
3 - The pipe operator (|) as in F#; which can be there if we have feature number 2.
4 - Tuples; I have implemented some tuple data structures; but without compiler support, it needs to be implemented for any number of them!
5 - Better type inference; For example for lambdas I wrote a static method 'infer' for that I be able to define Extension Methods on delegates or use them in Anonymous Types:
new
{
Target = "XPC 10",
Vel = ExSyntax.infer ((int a) =>
{
return a * 22.8;
})
};
or
ExSyntax.infer (() =>
{
return DateTime.Now.Second > 10;
}).do_while_true (() =>
{
Console.WriteLine ("Updating Report...");
});
6 - Anonymous Types everywhere; which in fact is "good Type Inference" every where. I think as the members of Anonymous Types are the static members of the container class; so we can apply synchronization and security facilities easily (I know you are the best and you are doing your best; so the "I think" part is just about the point of view from where that I am).
7 - Dynamic proxies; we can emit runtime types and cache them: declaring a new class that implements the target interface and has members of another type which is going to be have the interface (ducked!).
8 - Generic Generic Types; So I can define a typed linked list like this:
TyLList<A> {
public A Value;
public TyLList<?> Next;
}
9 - Named parameter calling for functions; for void F(int a, string b) calling it like F(b = "OK", a = 10)
10 - Default values for parameters
11 - Calling function with an Anonymous Type with members which are named after function arguments:
For void F(int a, string b) calling F like F(new { b="OK", a=100});
(We already have 9, 10 and 11 for attributes!)
12 - Metaprogramming; (not IL weaving) which already have proof of concept projects like F# (Active Patterns and Typed Quoting ...)
13 - An even very simple form of syntax extending; with 12 we will have enough of this
14 - A #light syntax for C#; as we have in F#, which can be some form of indentation-based code layout (like in F#) with possibility yet to enclose code blocks in {}s.
15 - Tagging types; which will provides us Class Cases, I have implemented for example Either<A,B>, some people implement this by declaring additional types like Left<A> and Right<B>; that is wrong! GADT are distingushed from the way that the object is constructed and the cases of the class in fact are different constructors which tag the object with different tags.
16 - 'this' refers to the current object; If there be somthing like this_type it is hand full (GetType is a runtime thing but this_type i.e. can be passed to Generics)
17 - Passing lambdas to attributes as parameter
18 - Defining Execution Contracts; like 'Ensure' and 'Requies' and with 14, even a new step in compiling a method or something.
19 - Capturing the values in the current execution context as a Name-Value dictionary; we have already the clousures and with 6, this would be very easy (this will provide us continuations).
20 - An attribute like [AloneExecutionPath] for methods; which grants that the methos just have access to it's parameters, and have not access to any public or internal thing in any assembly written by user (we can use .NET class library(is this good?) and to the Anonymous Types defined inside the function and we can pass objects of those types)
22 - Curry is necessary;
21 - OK! OK! ...
I was just looking into my codes and comming back here and write things! I close Visual Studio for now!
Maybe this is another language!
Thanks all!
Fancy code refactoring with extentension interface implemenations
I have been playing around with the wonderfull new extension methods, templates etc.
You can do some great things with the new IEumerator<T> list constructs.
One of the things i really like about these is that you can apply them consistently accross a number of different types.
It seemed logical to do the same type of thing with trees however here-in lies a problem there is no consistantly used interfce such as IEnumerator upon which to base such extensions.
You can of course create the same code multiple times each one for a different type, but this seems really messy and inefficient.
What would be usefull would to provide allow extension interface implementations - a bit like a multiple inheritance extension.
We could have something like:
public interface ITreeBase<T> // just a normal everyday interface
{
bool IsRoot();
IEmumerable<T> GetChildren();
}
// Now say we want extension methods to implement this inteface for a TreeNode we might have something like
public static class TreeNodeExtn:ITreeBase<TreeNode>
{
public bool IsRoot(this TreeNode This) { return false; }
public IEmumerable<TreeNode> GetChildren(this TreeNode This)
{
return This.Nodes;
}
}
// The above is ok - but we need to be specific about what class we are adding the inteface extension to.
// Also it would be nice to simplify the syntax a bit. So we we might re-write this something like:
public class TreeNodeExtn extends TreeNode :ITreeBase<TreeNode> // Note this is still just an Extension no real inheritence here
{
public bool IsRoot { get { return false;} }
public IEmumerable<TreeNode> GetChildren()
{
return this.Nodes;
}
}
OK so now we define this for some other types also as follows:
public static class TreeViewExtn extends TreeView: ITreeBase<TreeNode>
{
public bool IsRoot { get { return true; }}
public IEmumerable<TreeNode> GetChildren()
{
return This.Nodes;
}
}
public static class XPathNavigatorExtn extends XPathNavigator: ITreeBase<XPathNavigator> // note this is a static class with extension methods
{
public bool IsRoot { get {return false; }}
public IEmumerable<XPathNavigator> GetChildren()
{
while(var v in this.Children()) yield return v.current;
}
}
Now we can of course use these extension methods exactly as in before for items of one of the TreeNode,TreeView or XPathNavigator
So next we would like to write some generic tree handling extension methods using our new extensions as follows
public static class TreeBaseExtnMethods
{
public IEmumerable<T> Descendants<T>(this ITreeBase<T> This)
{
foreach(var v in This.Children())
{
yield return v;
foreach(var d in v.SelfAndDescendants())yield return d;
}
}
public IEmumerable<T> FindDescendant<T>(this ITreeBase<T> This,Func<T,bool> fn)
{
foreach(var v in This.Children())
{
if(fn(v)){ yield return v; yield break; }
foreach(var d in v.SelfAndDescendants(fn))yield return d;
}
}
.....
}
// OK looks nice but how will this work in practice.
// The complier will compile the TreebaseExtn methods as before.
// So for it to work the above functions actually need to be passed a class that implements ITreeBase<T>
// To achive this the compiler simply creates an instance class of each of the extension classes (TreeNode,TreeView or XPathNavigator).
// These class are simply container classes each one has exactly just one field "this" which refers to an instance of the object we are extending.
// So for the first example it in effect complies as:
public class TreeNodeExtn:ITreeBase<TreeNode>
{
prviate TreeNode This;
public bool IsRoot { get { return false;} }
public IEmumerable<TreeNode> GetChildren()
{
return This.Nodes;
}
public static implicit operator ITreeNodeExtn(TreeNode tn)
{
return new TreeNodeExtn { This=tn };
}
public static implicit operator TreeNode(TreeNodeExtn tn)
{
return tn.This;
}
}
// Lots of other nice stull you can do with the above... but thats for another day.
Some syntactic sugar?
Instead of code like:
{
using (var a=new c())
{
using(var b=new d())
{
.....
}
}
}
why not simply allow the scope to be implied by the enclosing braces?
{
var x = new myglocal();
local var a = new c() ;
local var b = new d();
}
Also how about a thread-safe null-checking dot operator .? to supplement the ?? operator.
so
var x= (a!=null)?a.fn():null
can be shortend to
var x = a.?fn();
For value-types the return value could be up-converted to a nullbable type as required.
int v = a?.MyIntFn() ?? mydefaultValue;
Invoking events/delegates could also be supported as folows
myevent.?(sended,args);
Removing one of the often -discussed current problems of how to achive this safely.
Remove this comment
Remove this thread
close