-
Notifications
You must be signed in to change notification settings - Fork 4.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
ADO.NET factory methods should throw instead of returning null #28768
Comments
Would that be a breaking change? https://github.com/dotnet/corefx/blob/master/Documentation/coding-guidelines/breaking-change-rules.md#exceptions /cc @terrajobst |
@benaadams the current methods don't throw any exceptions, so methods which previously returned a null (which could be checked) would now start throwing NotSupportedException - I think that's a breaking change, no? |
Sounds undesirable and breaking to me. If it was being done like this in the first place: fine, but after the fact? not good IMO. Personally I'd be OK with making it return an advertised nullable reference, as long as that only impacts people who have opted in to nullable testing. Just my tuppence. |
Follow up question that may change things: is the common pattern here to just |
@mgravell that pattern is not used in DbProviderFactory implementations, at least not commonly. But on the other hand, I know of very few (only one actually) provider implementations that don’t override all the required methods. |
@mgravell, while this change would apply to all methods on DbProviderFactory, most methods there are "mandatory" and it's very hard to imagine a provider which hasn't overridden them (e.g.
I think that the idea is to make the new nullability checking recommended and 1st-class experience, so forcing people who've opted into it to check all the time doesn't seem like a good way forward... @divega should we also add a An a final thought: for the mandatory methods on DbProviderFactory, we could go a bit further and make them abstract (rather than throw). Unless I'm mistaken, assuming providers have implemented them, this wouldn't even be a breaking change. |
Triage: We decided not to make the breaking change here as the value doesn't seem high enough. @roji to open a new issue with a different approach. |
Some ADO.NET APIs create objects which not all providers support. For example,
DbProviderFactory.CreateCommandBuilder()
returns aDbCommandBuilder
, but some providers don't support this functionality (e.g. SQLite if I'm not mistaken, @bricelam). The current implementation for all the methods on DbProviderFactory is to return null by default, which serves as a sort of "feature detection mechanism" - consumers can check if the result is null to know if the feature is supported or not.Aside being a generally problematic mechanism (users get NullReferenceException instead of the clearer NotSupportedException), this mechanism is also not suited for C# 8 nullability. If certain providers can return null to indicate that the feature isn't supported, than it seems like the
Create*()
method will return a nullable reference. This would impose on everyone to either check for null, or use the bang (!) operator to tell the compiler that no null is actually possible there - not good practice since users simply know that their specific provider supports the feature. Conversely, if theCreate*()
method returns a non-nullable reference, then you may get warnings for checking it for null.Instead, we should change these methods to throw NotSupportedException (breaking change), and add
Can*()
virtual bool properties alongside these methods to indicate whether the feature is supported or not (similar to howDbProviderFactory.CanCreateDataSourceEnumerator
exists alongsideDbProviderFactory.CreateDataSourceEnumerator()
. The default implementation of these capability properties could be to call the corresponding method, catching NotSupportedException and returning based on that.This should be done for .NET Standard 2.1 if possible.
Originally discussed in https://github.com/dotnet/corefx/issues/35135#issuecomment-466452344
The text was updated successfully, but these errors were encountered: