I have run across this issue plenty of times. I write up this sexy abstract design only to be reminded of this limitation with generics (it's present in Java as well):
interface IData {
void insert
}
class Foo : IData {
void insert(List
}
the implemented insert SHOULD satisfy the interface insert method (IMO) but it doesn't. I guess the general rule is for the compilers to look for an exact signature rather than a method that fulfills the requirements of the generic method. One cute way to get around this is with:
abstract AData {
void insert
insert(list);
}
}
class Foo : AData {
void insert(List
}
This however is a little dangerous, because I have no way to force the implementation of the concrete insert method. You could also cast to Foo in the implementation, but that creates a whole new set of possible complications.
It could be that this somehow doesn't fall with in the scope of generics. And maybe there is a plausable solution elsewhere in the language.. Dunno.
AlanPosted Jan 19, 2008, 10:14 AM
Sorry, Jeff, but the code I posted earlier is not what it seems :(
It had been worrying me how the code could possibly be typesafe if you were allowed to implement a generic interface method in that fashion when it suddenly struck me that IData and Foo are in fact method type parameters which hide the names of their enclosing types! So, you could in fact use absolutely any names and the code would still work. Moreover, there's nothing to constrain them to types which implement the IData interface unless you include a where clause as you did originally.
I'm surprised that you're allowed to use method type parameters which have the same name as the enclosing type itself which is very confusing but evidently you are.
So back to square one on this problem, I'm afraid.
JeffPosted Jan 18, 2008, 12:42 PM
AlanPosted Jan 18, 2008, 6:09 AM
Well, I'd always thought that the compiler required an exact signature match when checking whether a class implemented a particular interface method. I was therefore somewhat taken aback to find that the following code compiles and runs fine:
using System;
using System.Collections.Generic;
interface IData(List list);
{
void insert
}
class Foo : IData(List list)
{
public void insert
{
Console.WriteLine("Insert called");
}
}
class Program list = new List();
{
static void Main()
{
List
list.Add (new Foo());
Foo foo = new Foo();
foo.insert(list);
Console.ReadKey();
}
}
Generics are full of surprises - not all of them bad :)