Consider the following scenario.
I have a method which returns ISomething, but it could be Something or Wrapped<Something>.
I therefore cast the result to Something to use it, but it fails, any help as to why or how to resolve it would be greatly appreciated.
class Program
{
static void Main(string[] args)
{
var a = new DerivedSomething();
var b = (DerivedSomething)new Wrapped<DerivedSomething>(a); //success
var c = (DerivedSomething)_GetSomething(false); //success, obsiously!
var d = (DerivedSomething)_GetSomething(true); //Unable to cast object of type 'test_bed.Wrapped`1[test_bed.DerivedSomething]' to type 'test_bed.DerivedSomething'.
var e = (DerivedSomething)(ISomething)new Wrapped<DerivedSomething>(a); //Unable to cast object of type 'test_bed.Wrapped`1[test_bed.DerivedSomething]' to type 'test_bed.DerivedSomething'.
var works = ((DerivedSomething)_GetSomething(false)).DoSomethingElse();
var fails = ((DerivedSomething)_GetSomething(true)).DoSomethingElse(); //cast exception
}
private static ISomething _GetSomething(bool wrap)
{
var something = new DerivedSomething();
return wrap ? new Wrapped<DerivedSomething>(something) : (ISomething)something;
}
}
public interface ISomething
{
void DoSomething();
}
public abstract class Something : ISomething
{
public void DoSomething()
{
//some code
}
}
public class DerivedSomething : Something
{
public void DoSomething()
{
//some code
}
public void DoSomethingElse()
{
//some code
}
}
public class Wrapped<T> : ISomething
where T : ISomething
{
private readonly T _something;
public Wrapped(T something)
{
_something = something;
}
public void DoSomething()
{
_something.DoSomething();
}
public static explicit operator T(Wrapped<T> wrapped)
{
return wrapped._something;
}
}
It appears that if the type is exposed as the interface when trying to cast, then the operator is not found?
The ‘easy’ solution would be to write a ‘unwrap’ function which optionally unwraps the Wrapped<Something> to Something, but i’d prefer to use operators if possible.
Edit
I think the crux of the problem is: outside of _GetSomething() i wont know whether Something or Wrapped<Something> is going to be returned.
You cast operator looks like this:
and you’re casting like
You can not cast to
Something, causeSomethingis a concrete implementation of theT:ISomething. TO make this work you need to write:or
if you really want to use concrete type, you can define generic like: