What Language Features Do You Miss In C#?
-
you can type several 'case' statements one after the other. contrived example:
int number = GetNumberBetween1And5();
string text = null;
switch( number ) {
case 1:
text = "1";
break;
case 2:
case 3:
case 4:
text = "2 or 3 or 4";
break;
case 5:
text = "5";
break;
}is that type of fall-through what you said you're missing?
I already knew about (and use) that type of fallthrough (but thanks for pointing it out anyway). I'm talking about a case (no pun intended) where you have an action to perform in two cases that requires some kind of setup in one of the cases but not the other.
switch(whichAction)
{
case Actions.ActionWithSetup:
DoSetup();
case Actions.Action:
DoAction();
break;
}In this example, in the one case, DoSetup is performed, followed by DoAction; in the other case only DoAction is performed. You can do this in C (and Java as I recall) but not in C#. I'm fine with the language not allowing the fallthrough to happen unintentionally but think there should be a keyword to allow it. For example:
switch(whichAction)
{
case Actions.ActionWithSetup:
DoSetup();
nobreak;
case Actions.Action:
DoAction();
break;
}I realize that in my example I could simply call DoAction in both cases (and that's what I would do, given the C# limitation); and I also understand that if I've got a block of code in the second case, I can break it out into a separate method and call that method in both cases (which again is what I would do); however, if it's a really small block of code, I don't necessarily want to create a new method for it or duplicate the code.
-
I already knew about (and use) that type of fallthrough (but thanks for pointing it out anyway). I'm talking about a case (no pun intended) where you have an action to perform in two cases that requires some kind of setup in one of the cases but not the other.
switch(whichAction)
{
case Actions.ActionWithSetup:
DoSetup();
case Actions.Action:
DoAction();
break;
}In this example, in the one case, DoSetup is performed, followed by DoAction; in the other case only DoAction is performed. You can do this in C (and Java as I recall) but not in C#. I'm fine with the language not allowing the fallthrough to happen unintentionally but think there should be a keyword to allow it. For example:
switch(whichAction)
{
case Actions.ActionWithSetup:
DoSetup();
nobreak;
case Actions.Action:
DoAction();
break;
}I realize that in my example I could simply call DoAction in both cases (and that's what I would do, given the C# limitation); and I also understand that if I've got a block of code in the second case, I can break it out into a separate method and call that method in both cases (which again is what I would do); however, if it's a really small block of code, I don't necessarily want to create a new method for it or duplicate the code.
-
Inline assembler.
I believe that's been there since version 1.0
-
sprintf sscanf
Steve Wellens
Amen, would make life easier at the moment! mind you can get them from C++ Glenn
-
VB error handling, really?
-
Sure, it's on another discussion site[^], but that doesn't mean we can't also discuss it here. Personally, while it certainly doesn't fit in the "missing" category, I see them moving it closer and closer to a hybrid C#/JavaScript language with each new version.
-------------- TTFN - Kent
Enum that supports other types, not just integral types. A required tag on the end of block regions. Why? Cause it can become a bitch knowing which '}' belongs with what after a while and folks are too lazy to comment. Or VS could get better and put a comment there for you. But then this isn't about VS. Improved Friend relationships between DLL's. Current way of setting up Friend relationships is awkward.
-
why the heck you just don't use a generic method?
public void DoGenericStuff(Foo foo)
{
....
}I'm brazilian and english (well, human languages in general) aren't my best skill, so, sorry by my english. (if you want we can speak in C# or VB.Net =p) "Given the chance I'd rather work smart than work hard." - PHS241
Hahahahaha. You didn't get it at all. Imagine that for some reason you don't know the T type at compile-time. You are in an event or something and you are receiving a valid value, but it is cast as object. How do you do a call to the generic class without knowing its generic type? In such case, it is up to you to do the cast, but you don't have the destination type at compile time. The solution in such situation is to use reflection or dynamic. I solve the problem having an untyped interface. That works very well for my classes, but not to already existing classes. Even if it is not a generic class situation, you can see that happening with database connections. You have SqlConnection, OracleConnection, SqlCommand, OracleCommand, SqlParameter, OracleParameter and so on. But you can use all of them al IDbConnection, IDbCommand and so on. So, you create a parameter using the command... you dont know if it is an OracleParameter or SqlParameter... but it is not important, as when you add a parameter to a command the driver do the cast for you. (Ok, it is a little stupid that you create the parameter and it is not added automatically... but I want to ilustrate a situation where you have a valid value [the parameter] but you don't have the valid type).
-
A
goto case
is not agoto
. But, yes, I don't likebreak
in aswitch
; in my opinionbreak
should only be for loops only.I do not really agree, since
case
statements form a valid label andgoto
LABEL is a realgoto
. Why was goto brought to C (and therefore to C++, C#, ...) anyway? It is REALLY simple to implementgoto
in C (for transferring into assembler). Its jut a plainJMP
. Labels can be transferred nearly 1-1, so having agoto
the way it has been introduced to C makes sense.switch-case
statements have just a list ofJE
statements, i.e. usinggoto
is the way to use those labels outside of the usual flow. Here is howswitch-case
results in MSIL:IL_0001: ldc.i4.5
IL_0002: stloc.0 // a
IL_0003: ldloc.0 // a
IL_0004: stloc.1 // CS$4$0000
IL_0005: ldloc.1 // CS$4$0000
IL_0006: switch (IL_0015, IL_0022)
IL_0013: br.s IL_002F
IL_0015: ldstr "Zero"
IL_001A: call LINQPad.Extensions.Dump
IL_001F: pop
IL_0020: br.s IL_003C
IL_0022: ldstr "Zero"
IL_0027: call LINQPad.Extensions.Dump
IL_002C: pop
IL_002D: br.s IL_003C
IL_002F: ldstr "Nothing"
IL_0034: call LINQPad.Extensions.Dump
IL_0039: pop
IL_003A: br.s IL_003CThe line IL_0006 will result in the list of
JE
statements. The following program was used to produce these lines of IL code:void Main()
{
var a = 5;switch(a) { case 0: "Zero".Dump(); break; case 1: "One".Dump(); break; default: "Non-Zero".Dump(); break; }
}
If you would now compare this to usual labels you would see that both are identical. It's really just a syntax thing that case statements start with
case
, hence since one has always to specify the full label, thecase
needs to be included for anygoto
call on those labels. -
Sure, it's on another discussion site[^], but that doesn't mean we can't also discuss it here. Personally, while it certainly doesn't fit in the "missing" category, I see them moving it closer and closer to a hybrid C#/JavaScript language with each new version.
-------------- TTFN - Kent
- Extension properties and operators. - An analogue to the ?? operator that returns null if any object in a chain of lookups is null, e.g. var furniture = house.livingroom.sofa without having to null-check every step. - Return type covariance. - typedef support, mainly to alias a pervasively used ugly generic type without needing to put a using statement in every file. More useful for value types that can't be subclassed to achieve similar ends.
-
Yes! And gosub.
-------------- TTFN - Kent
-
Hahahahaha. You didn't get it at all. Imagine that for some reason you don't know the T type at compile-time. You are in an event or something and you are receiving a valid value, but it is cast as object. How do you do a call to the generic class without knowing its generic type? In such case, it is up to you to do the cast, but you don't have the destination type at compile time. The solution in such situation is to use reflection or dynamic. I solve the problem having an untyped interface. That works very well for my classes, but not to already existing classes. Even if it is not a generic class situation, you can see that happening with database connections. You have SqlConnection, OracleConnection, SqlCommand, OracleCommand, SqlParameter, OracleParameter and so on. But you can use all of them al IDbConnection, IDbCommand and so on. So, you create a parameter using the command... you dont know if it is an OracleParameter or SqlParameter... but it is not important, as when you add a parameter to a command the driver do the cast for you. (Ok, it is a little stupid that you create the parameter and it is not added automatically... but I want to ilustrate a situation where you have a valid value [the parameter] but you don't have the valid type).
if you know the interface you can always cast to IFoo. thanks to Covariance[^]
I'm brazilian and english (well, human languages in general) aren't my best skill, so, sorry by my english. (if you want we can speak in C# or VB.Net =p) "Given the chance I'd rather work smart than work hard." - PHS241
-
sprintf sscanf
Steve Wellens
I don't know about sscanf, but String.Format() doesn't do the trick for when you need sprintf?
I'm brazilian and english (well, human languages in general) aren't my best skill, so, sorry by my english. (if you want we can speak in C# or VB.Net =p) "Given the chance I'd rather work smart than work hard." - PHS241
-
I agree. Multiple inheritance can be an elegant, simple, effective solution to many design problems. It's left out because there are contrived cases where it produces complexity, but these are just bad programming.
-
if you know the interface you can always cast to IFoo. thanks to Covariance[^]
I'm brazilian and english (well, human languages in general) aren't my best skill, so, sorry by my english. (if you want we can speak in C# or VB.Net =p) "Given the chance I'd rather work smart than work hard." - PHS241
That works for IEnumerable but not for IList (to show a limitation). In fact, if you need to give parameters to the Foo object (in the command case, you add a parameter to the command) it can at maximum be an "in T", so you can't use IFoo<object> Also, even "out T" will not work which structs. Try to get an IEnumerator<int> as an IEnumerator<object>. It does not work. But for such situation there is the non-generic that works in a more generic way... you can use an IEnumerator without a generic parameter. In such case there is such interface, but that's not always the case. And as a note... using IFoo<object> is contravariance, not covariance.
-
Sure, it's on another discussion site[^], but that doesn't mean we can't also discuss it here. Personally, while it certainly doesn't fit in the "missing" category, I see them moving it closer and closer to a hybrid C#/JavaScript language with each new version.
-------------- TTFN - Kent
The ability to look at a variable's memory location while in another part of the program. In C++, I sometimes use what I call the "Stakeout Debugging Pattern": I create a Watch expression on the address of a variable, so I can see how it changes while not in scope. (The debugger won't show variables not in scope). E.g. *(int *)0x12345678 But there's no way (that I know of) to do this in C#. This would help with debugging.
-
Sure, it's on another discussion site[^], but that doesn't mean we can't also discuss it here. Personally, while it certainly doesn't fit in the "missing" category, I see them moving it closer and closer to a hybrid C#/JavaScript language with each new version.
-------------- TTFN - Kent
-
Multiple inheritance. Interfaces are useful as abstractions, but there are times I want to inherit concrete functionality from multiple classes. Marc
Latest Article: C# and Ruby Classes: A Deep Dive
My BlogI completely agree. Even if we can simulate multiple inheritance with interfaces and extension methods, well, extension methods are ugly, require a special using to be available and can't be virtual. So, multiple inheritance will be great. And if there are persons that use it incorrectly, well... there are persons that do all kinds of stupid things.
-
Sure, it's on another discussion site[^], but that doesn't mean we can't also discuss it here. Personally, while it certainly doesn't fit in the "missing" category, I see them moving it closer and closer to a hybrid C#/JavaScript language with each new version.
-------------- TTFN - Kent
THROWS, as an optional declaration. I would like the following... public void myfunction(int x) throws ArgumentException, OverflowException { } And, Java needs the other form of throws too, which I'd like to see in C# public void myfunction(int x) throws NONE { } ... for methods which can't throw exceptions.
-
I believe that's been there since version 1.0
Riiiiight...
-
This one is type dependent and not a language future but some class method. Same as Split() (very useful method by the way) or IsNullOrEmpty() for example.
There is only one Vera Farmiga and Salma Hayek is her prophet! Advertise here – minimum three posts per day are guaranteed.
What does it matter that it's a framework implementation and not implemented by the C# specification? Just as long as it accomplishes the same thing.