-
Notifications
You must be signed in to change notification settings - Fork 4k
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
Implicit interface conversion #14186
Comments
I don't think the "extension everything" feature will, but a feature that is part of pattern matching (but which isn't being released with C# 7) will address this. A new operator, public static bool operator is(AdapterType adapter, out AdaptedType original)
{
original = convert from adapter to original;
return true if conversion works;
} And it can then be used like: if (original is AdapterType adapter)
{
// user adapter here
} |
That prohibition is intentional in order to avoid the ambiguity in attempting to resolve an assignment between a conversion and a simple cast. The conversion operators are intended to bridge between two types which are otherwise incompatible with one another. The spec further explicitly prohibits redefining existing conversion operations, which would include downcasts. |
would it be safe to support only implicit conversion from interfaces? |
I just hit this issue, and the restriction is making life rather difficult. We've decided that, where possible, the library limits public types to interfaces. The unfortunate part is that classes cannot implement Here's the actual scenario. We have two interfaces |
@whoisj What you're describing should work. Are you sure there isn't something else going on in your code? |
No. This is a large code base, there could be other things happening. However, it seems consistent to me. Perhaps there's some hierarchy of interface inheritance that is causing issues? |
That's not the behavior of C#. The type of the instance doesn't change depending on the type of the variable. Sounds like that project is wrapping those instances, either directly or via proxy, so that the instance you are working with are actually not instances of |
I've run into this as well - from a different angle. Playing around quite some time ago, I had defined an interface Essentially, I had this code:
and I wanted to be able to write this:
which requires both defining an implicit cast from |
@theunrepentantgeek that is basically identical to what I was attempting to express, but significantly more clear and less confusing. Thanks 😄 |
I've run into this issue as well: struct Optional<TValue>
{
public Optional(TValue value)
{
_Value = value;
_HasValue = true;
}
TValue _Value;
bool _HasValue;
public TValue Value
{
get
{
if (!_HasValue)
throw new Exception("Optional value not present.");
return _Value;
}
}
public bool HasValue => _HasValue;
public static implicit operator Optional<TValue>(TValue value) => new Optional<TValue>(value);
} The usage scenarios: Optional<int> a = 0; // works
Optional<string> b = null; // works
System.IO.Stream stream = null;
Optional<System.IO.Stream> c = stream; // works
IDisposable disposable = null;
Optional<IDisposable> d = disposable; // DOES NOT WORK Is there any ongoing work to solve this in future C# versions? Please note that |
I am wondering if this is also something I have recently had problems with... My wrapper looks something like this:
My consumer looks something like this:
I have a set of NUnit tests (using NSubstitute & FluentAssertions) that looks something like this:
In my test "Should_implicitly_convert_wrapper_inline" inside the I could be wrong that this is related to this issue, but it seems very close to me and I couldn't find anything else similar that matched my issue. However I didn't want to create a duplicate if this issue is close enough. Any thoughts welcome on this. |
I came across this problem today, three years after beginning this issue here. |
This feature can reduce annoying code. Is there any plans to implement it? |
I'm also interested in this. This seems like an arbitrary limitation. |
I'd prefer it if C# supported implicit-conversion and explicit-conversion through an interface that's part of the BCL, instead of through only the What I'd like to see is something like this as a standard interface:
This would be useful in many cases and conveniently side-steps Eric Lippert's discussion about not wanting user-defined conversions to replace built-in conversions that preserve object-identity. But this could be made even better by adding a new C# keyword
Where the
Right now I implement this And it could be made even better by adding a postfix "try-convert" operator for succint parameter conversion through the above interfaces without needing to muddy our code with explicit calls to conversion methods. |
The runtime and C# teams are currently exploring the possibility of interfaces having static members, one of the primary use cases being to support operators for generic math, but it also would apply to generic conversion operators. This is a part of a larger project called "shapes"/"roles" which expands on the use of interfaces as generic constraints even where the generic type argument doesn't implicit the interface directly.
The I think that would cover the cases you described. |
Closing this out. We're doing all language design now at dotnet/csharplang. If you're still interested in this idea let us know and we can migrate this over to a discussion in that repo. Thanks! |
Today's implementation of implicit conversion operators doesn't allow interfaces to participate - only abstract classes, which isn't always possible or desirable (as interface is generally better than abstract class if you're planning your type hierarchy).
Why it's important? It allow to use adapter pattern transparently. You can write or generate (using upcoming "source generators" feature) adapter for certain interface and if implicit interface conversion is possible you could simply omit explicit adapter instantiation and use classes (which have adapter for certain interface + implicit conversion operator to certain interface) just in place of adapted interface.
It's all possible if you use abstract classes (implicit conversion operators are only applicable for classes and structs), but not for interfaces. It's a huge miss as many people (including me) prefer to use interfaces instead of abstract classes to handle polymorphism when possible.
How "extension everything" upcoming language feature would handle implicit interface conversion case?
The text was updated successfully, but these errors were encountered: