phancey@googlemail.com wrote:
Quote:
[...]
Now that I write this more
clearly I start to understand that the compiler does not know that
another object might be sent to this method.
I believe that is true. What I was playing with regarding constraints
was having both T and Wrapper<Tinherit a common interface, so that
they could be treated the same. But in that case, all that the compiler
knows still is that they implement the common interface. That means the
"manager" method would have to be changed to take an object with the
common interface as a parameter, rather than using the overload. That's
possible, but it introduces new complexities itself.
The basic issue here is that with generics, the compiler needs to know
what method is going to be called when it compiles the code. More
problematically, it can't defer that until some concrete use of the
generic. Everything the compiler needs to know must be known when
compiling the generic class itself (consider generic classes implemented
in a pre-compiled assembly, like those already in .NET, for example),
and generics don't provide any way for you to relate T and Wrapper<Tin
a way that makes sense at compile time.
In the error you're getting, the compiler has selected an overload
already -- it has to pick the overload at compile time -- and then it
finds that it doesn't have enough information to consistently ensure
that the parameter passed to the overload is always what it needs. Thus
the error.
Quote:
What I need is to be able
to tell it that E is either T or Wrapper<Tbut I don't think this is
possible. I suppose I will need to use overloaded methods here but I
was trying to avoid that because all of the code is actually generic
for that method on the assumption you know it is only one of these 2
types that will be sent in :o(
>
If anyone has any further advice I would appreciate it.
I agree with your assessment that exactly what you want isn't possible.
However, I will say that often when I find that I'm unable to do
something with generics that I'd like to do, if I take a step back and
try to figure out what it is about my underlying design that imposes the
desire to use generics in a specific way, I discover that my underlying
design is leading me down a path that's itself not a desirable one.
In a way, the barricade I run into with respect to the generic
implementation is actually a big warning flag saying that my basic
design could be improved.
Whether this is the case in your situation, I don't know. You would
have to look at a wider picture than what you've shown here, I think.
Just as an example though, do you really need to put your "value-added"
stuff in a generic "Wrapper<>" class? Or does that Wrapper<class need
to be structured in exactly the way it is? I haven't thought about this
much, but if Wrapper<Tactually inherited T, then you could always pass
a Wrapper<Tto any method that took a T. You wouldn't need to use
overloads, but the methods would have to check the object passed in to
see whether it's a Wrapper<Tor just a plain T.
Anyway, that's just an example...if that doesn't actually work, there
are other ways to create a data structure that can be, essentially "T,
or T+other stuff" in a way that is more compatible with generics (that
is, more of the logic happens at run-time, getting around the problem
that at compile time there's not enough information to resolve ambiguities).
Pete