This is confusing, as I'm getting seemingly contradictive errors.
I'm using generics, constraining T
to Something
, then constraining U
to AnOperation<Something>
.
I expected that an object AnOperation<Something>
is from now on considered of type U
. But, I'm getting errors:
Cannot implicitly convert type 'ConsoleApp1.AnOperation<T>' to 'U'
That's weird. Well, i tried explicitly casting it to U, then I got this error:
Cannot convert type 'ConsoleApp1.AnOperation<T>' to 'U'
which also stated Cast is redundant
namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
}
}
class MyClass<T, U>
where T : Something
where U : AnOperation<Something>
{
public U GetAnOperationOfSomething()
{
AnOperation<T> anOperation = new AnOperation<T>();
return anOperation; // Cannot implicitly convert type 'ConsoleApp1.AnOperation<T>' to 'U'
// return (U)anOperation; // Cannot convert type 'ConsoleApp1.AnOperation<T>' to 'U' also Cast is redundant
}
}
public class Something
{
}
public class AnOperation<T>
where T : Something
{
}
}
What's happening here?
Edit: I'm trying to understand what is the problem in the language level, not looking for a workaround on an actual problem.
You almost got it right with your constraint, but not quite. You define
where U : AnOperation<Something>
But then you create
AnOperation<T> anOperation = new AnOperation<T>()
That is not the same thing. If you change your constraint to...
where U : AnOperation<T>
...you will be fine.
Another problem is that while every U
is an AnOperation<T>
, not every AnOperation<T>
is an U
. When you declare...
public U GetAnOperationOfSomething()
...you are making the guarantee that what the method returns is an U
. AnOperation<T>
can not satisfy that guarantee.
You are solving this with a typecast to U
. That is against the purpose of your generic class, since every U
must be an AnOperation<T>
or you will get a runtime exception. That makes the whole type parameter U
unnecessary. What you actually want to do is create an U
. You can use the new()
constraint for that:
class MyClass<T, U>
where T : Something
where U : AnOperation<T>, new()
{
public U GetAnOperationOfSomething()
{
U anOperation = new U();
//...
return anOperation;
}
}
The new()
constraint guarantees that U
will have a public default constructor, which you can invoke.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With