Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
C#’s default keyword has two kinds of usages: one is to label the fallback branch of the switch…case structure (for any path that does not fall into the case conditions); another is to represent the “default” value of a type. I will discuss this usage in this blog.
The default value of a type is either:
- null, if the type is a reference type, or
- an instance of the type constructed with the parameterless constructor, if the type is a value type.
The following screenshot is a quick example.
However, you can not have a default expression for any open type (Note: An open type is a type that has unbound type arguments; a type has all bound type arguments is called closed type), for example:
Now, if we want to use default value for a generic type in a method, we have to write code like this:
public static void Method(ImmutableArray<int> array) { }
public static void Main(string[] args)
{
Method(default(ImmutableArray<int>));
}
Do you see a redundant here? the compiler should know the exact type needed for the Method() for the first parameter. A default literal without the type specification should be sufficient enough.
Default Literals
C# 7.1 allows the default expressions. If compile with the C# language version 7.1, or latest, you can simplify the code as the following:
public static void Method(ImmutableArray<int> array) { }
public static void Main(string[] args)
{
Method(default);
}
Now you get a clean code!
Similarly, you can have default literals for all the place that default(…) can appear:
public static void Main(string[] args = default) // Default value for the optional parameter {
int i = default; // Default value (0) for type System.Int32
string s = default; // Default value (null) for type System.String
Method(default); // Calling a method with default value for an argument
T t = default; // Default value for a type parameter
return default; // Default return value for a method that does not return void
}
You can have default literals in a condition test:
int x = 2;
if (x == default) { } // Test if x is default value (0) of the type System.Int32
if (x is default) { } // Same as above
More interestingly, you can use default literals in switch…case. Oh, cool! but… wait, how about the label ‘case default’? Here is what I get from the IDE:
And if you apply the fix, it will be:
int x = 2;
switch (x)
{
case (default): break;
default: break;
}
This looks confusing, but at least we get live analytics about this, Thanks Roslyn!
The last thing I want to call out is there are cases that cannot apply default literals, for example:
// Error: 'as' must have reference type
default as int;
// OK. But the left hand expression is always null.
if (default as string == string.Empty) { }
// Error. Cannot apply operator 'is' to type 'default'.
if (default is string) { }
Conclusion
Default literals in C# 7.1 avoids redundant typing where the default value is known to compiler. This is a syntactical improvement and nothing changed for the CLR, The new code is 100% compatible with the code built by earlier versions of the C# compiler.
Comments
- Anonymous
June 06, 2017
How do you differentiate between 'case default' and 'default' in goto statements? Would it be 'goto (default)' vs 'goto default'?- Anonymous
June 06, 2017
Ah it would be 'goto case default', doh! Sorry Mark. - Anonymous
June 12, 2017
If you need use "goto" statement in your code that means something goes terribly wrong- Anonymous
June 16, 2017
I would say it really depend on what problem needs to solve by "goto". There are cases such as switch-case that use 'fall through' requires "goto", e.g.switch (i){case 0: // direct fall-through without using "goto", as no body inside this "case".case 1: // something done here goto case 2; // we need "goto" here as there IS body.case 2: // do things break;default: break;}Of course you are saying other kinds of "goto" (from traditional C/C++ thought), unfortunately, I also saw some code from .NET Core that really requires this kind of goto in order to write less similar-to-same code.
- Anonymous
- Anonymous
- Anonymous
June 06, 2017
What if you have multiple parameters in a method? In my opinion the default keyword is much less readable than having the type as parameter. For example:Method(default(ImmutableArray), default(ImmutableArray), default(ImmutableArray));vsMethod(default, default, default); // hard to remember which one is which?- Anonymous
June 12, 2017
In my opinion if you want to allow for this kind situation is better to introduce optional parameters:Method(ImmutableArray a = default, ImmutableArray b = default, ImmutableArray c = default) - Anonymous
June 13, 2017
This is true for any literal. I am working on a c# 7.2 feature to address this: an improvement to named arguments. You will be able to writeM(ignoreEmpty: true, accumulator, cancellation: default);
.It is more informative to specify the name of the argument, than the type indefault
.
- Anonymous
- Anonymous
June 12, 2017
why not a three letter word like "def" instead of "default" .. you don't use def anywhere in c# seriously "default" will creap in the code.. =) , even just underscore "_" would have been better than both.. return _ ;string[] args = _ ;- Anonymous
June 14, 2017
Many people, me included, will always choose readability over length of the code. There's no way I could choose cryptic special characters over plain English words.
- Anonymous
- Anonymous
January 25, 2019
The default literal is never constructed with the parameterless constructor.Most value types don't have a parameterless constructor.If you happen to find one, it is invoked only with a 'new' expression. - Anonymous
May 22, 2019
when redundant vs readable/maintainable, which one do you choose?