Two of my most frequent issues with .net inconsistencies
-
I'm guessing it has to do with people's obsessions about breaking changes.
Robust Services Core | Software Techniques for Lemmings | Articles
The fox knows many things, but the hedgehog knows one big thing.That's why they can't fix it now, but it doesn't explain how things got that way to begin with, from v1 and earlier.
-
That's why they can't fix it now, but it doesn't explain how things got that way to begin with, from v1 and earlier.
From v1? Gee. Maybe there were bun fights over the interface. :)
Robust Services Core | Software Techniques for Lemmings | Articles
The fox knows many things, but the hedgehog knows one big thing. -
In my opinion... .net should never have been released to the public with such inconsistencies as these. :doh:
System.DateTime.UtcNow .ToString ( "hh:mm:ss" ) ;
System.DateTime.UtcNow.TimeOfDay.ToString ( "hh\\:mm\\:ss" ) ;new System.ArgumentException ( message , paramName ) ;
new System.ArgumentNullException ( paramName , message ) ;The
DateTime
vsTimeSpan
is more insidious than you think.DateTime.UtcNow.TimeOfDay.ToString("hh\\:mm\\:ss")
will always use ":" as the separator, whereasDateTime.UtcNow.ToString("hh:mm:ss")
will use the current culture's time separator. Whilst the default seems to use ":" consistently, I believe the user can override this in the OS settings.var format = new DateTimeFormatInfo { TimeSeparator = "#" };
DateTime.UtcNow.ToString("hh:mm:ss", format); // 07#56#00
DateTime.UtcNow.TimeOfDay.ToString("hh\\:mm\\:ss", format); // 07:56:00The argument exception one is annoying, but I can sort-of understand how it came to be. With an
ArgumentNullException
, there's an obvious default error message, and the main thing you care about is the name of the argument which wasnull
. But with anArgumentException
, there's no obvious default error message, and the error could be caused by a combination of parameters, so the message is the main thing, and the parameter name is optional. Since C# 4 introduced named parameters, you can use them to make the invocations consistent:new ArgumentException(paramName: nameof(foo), message: "Bar");
new ArgumentNullException(paramName: nameof(foo), message: "Bar");NB: Starting with .NET 6, the recommendation is to use
ArgumentNullException.ThrowIfNull(parameter);
instead ofif (parameter is null) throw new ArgumentNullException(nameof(parameter));
: ArgumentNullException.ThrowIfNull Method (System) | Microsoft Docs[^] Introduce static methods to allocate and throw key exception types. · Issue #48573 · dotnet/runtime · GitHub[^]
"These people looked deep within my soul and assigned me a number based on the order in which I joined." - Homer
-
The
DateTime
vsTimeSpan
is more insidious than you think.DateTime.UtcNow.TimeOfDay.ToString("hh\\:mm\\:ss")
will always use ":" as the separator, whereasDateTime.UtcNow.ToString("hh:mm:ss")
will use the current culture's time separator. Whilst the default seems to use ":" consistently, I believe the user can override this in the OS settings.var format = new DateTimeFormatInfo { TimeSeparator = "#" };
DateTime.UtcNow.ToString("hh:mm:ss", format); // 07#56#00
DateTime.UtcNow.TimeOfDay.ToString("hh\\:mm\\:ss", format); // 07:56:00The argument exception one is annoying, but I can sort-of understand how it came to be. With an
ArgumentNullException
, there's an obvious default error message, and the main thing you care about is the name of the argument which wasnull
. But with anArgumentException
, there's no obvious default error message, and the error could be caused by a combination of parameters, so the message is the main thing, and the parameter name is optional. Since C# 4 introduced named parameters, you can use them to make the invocations consistent:new ArgumentException(paramName: nameof(foo), message: "Bar");
new ArgumentNullException(paramName: nameof(foo), message: "Bar");NB: Starting with .NET 6, the recommendation is to use
ArgumentNullException.ThrowIfNull(parameter);
instead ofif (parameter is null) throw new ArgumentNullException(nameof(parameter));
: ArgumentNullException.ThrowIfNull Method (System) | Microsoft Docs[^] Introduce static methods to allocate and throw key exception types. · Issue #48573 · dotnet/runtime · GitHub[^]
"These people looked deep within my soul and assigned me a number based on the order in which I joined." - Homer
I don't use .net 6 . How would I specify the message though? Edit: In fact I don't use any features of C# 4 either. And it may be that the only features I use of C# 3 are Extension Method, Collection Initializer, and Object Initializer. I just ran through some of my libraries, seeing which require C# 3. Most do, but one will actually compile with C# 2. And I had actually forgotten about Collection Initializer until this week -- I used it in two places in a piece of code I wrote in 2014, to initialize a Dictionary. Last week I wrote some code which used a Dictionary Initializer, not realizing it is a C# 6 feature, and then rewrote it as a Collection Initializer when I found out. In the code I am working on, the Dictionary Initializer provides no benefit over the Collection Initializer.
-
I don't use .net 6 . How would I specify the message though? Edit: In fact I don't use any features of C# 4 either. And it may be that the only features I use of C# 3 are Extension Method, Collection Initializer, and Object Initializer. I just ran through some of my libraries, seeing which require C# 3. Most do, but one will actually compile with C# 2. And I had actually forgotten about Collection Initializer until this week -- I used it in two places in a piece of code I wrote in 2014, to initialize a Dictionary. Last week I wrote some code which used a Dictionary Initializer, not realizing it is a C# 6 feature, and then rewrote it as a Collection Initializer when I found out. In the code I am working on, the Dictionary Initializer provides no benefit over the Collection Initializer.
You wouldn't; the
ThrowIfNull
method always uses the default error message, which leads to more consistent errors. You could override the parameter name, but it's best to let the compiler fill it in using the[CallerArgumentExpression]
attribute.
"These people looked deep within my soul and assigned me a number based on the order in which I joined." - Homer
-
You wouldn't; the
ThrowIfNull
method always uses the default error message, which leads to more consistent errors. You could override the parameter name, but it's best to let the compiler fill it in using the[CallerArgumentExpression]
attribute.
"These people looked deep within my soul and assigned me a number based on the order in which I joined." - Homer
Seems pointless anyway. Why would I want a "default error message"? Or, if I do, I'd make that an inner exception and provide a meaningful message in the main exception. So far I have found no useful features of C# 6... except... I just found that "dictionary initializer" is a C# 6 feature and I have been toying with that for a week or so now. Why didn't this exist since the advent of initializers? I also just dabbled with string interpolation -- which I heard about, but hadn't bothered with -- and, as expected, it provides no benefit to me. It works only with string literals, and most format strings I use are not literals. It looks like it would lead to bad practices. In particular, how do you use string interpolation with globalization? Anyway, now that I know that I am using a v6 compiler, I can see if that's why my recent builds refuse to execute on the servers. I'll specify v4 and see if they succeed then. Edit: In case anyone is curious. Yes, once I rebuilt with an earlier compiler (v5), I was able to run the utility on the server. I am not in control of what versions of things (e.g. .net) are installed on my laptop and the servers, but it's never the latest version.
-
In my opinion... .net should never have been released to the public with such inconsistencies as these. :doh:
System.DateTime.UtcNow .ToString ( "hh:mm:ss" ) ;
System.DateTime.UtcNow.TimeOfDay.ToString ( "hh\\:mm\\:ss" ) ;new System.ArgumentException ( message , paramName ) ;
new System.ArgumentNullException ( paramName , message ) ;Aren't there similar quirks with the DateFormat? And what about NumberFormat (like decimal separator etc.)?
Oh sanctissimi Wilhelmus, Theodorus, et Fredericus!
-
Aren't there similar quirks with the DateFormat? And what about NumberFormat (like decimal separator etc.)?
Oh sanctissimi Wilhelmus, Theodorus, et Fredericus!
I think so. Plus in the past I've run into issues with other limitations on what can be specified in format strings. Which led to this : ApplyFormat[^] And this week I've been working on another formatter, kinda sorta similar to string interpolation, but not really.
-
In my opinion... .net should never have been released to the public with such inconsistencies as these. :doh:
System.DateTime.UtcNow .ToString ( "hh:mm:ss" ) ;
System.DateTime.UtcNow.TimeOfDay.ToString ( "hh\\:mm\\:ss" ) ;new System.ArgumentException ( message , paramName ) ;
new System.ArgumentNullException ( paramName , message ) ;How much money should they spend, in your opinion, to have parameters in the same order, even if it doesn't make sense? :|
Bastard Programmer from Hell :suss: "If you just follow the bacon Eddy, wherever it leads you, then you won't have to think about politics." -- Some Bell.
-
That's why they can't fix it now, but it doesn't explain how things got that way to begin with, from v1 and earlier.