I have a generic interface where the type constraint is an abstract base class.
So the implementations may be of different implementations.
Although this is fine, when I try to return a concrete implementation (such as ITestImplementation) from a method which is set to return the interface (eg ITest), this throws various compile time errors in Visual Studio about implicit casts.
Code:
ITest<Control>
{
v开发者_JAVA百科oid Execute();
}
I use this interface in various places and return a method as above. Maybe I should use a generic type placeholder.
Is this not possible?
Thanks
What you want is generic variance; specifically, you want Interface1 to be covariant.
Generic variance is not supported in C# 3. It will be in C# 4. Your code will work if you say
interface Interface1<out T>
However, you are then required to only use T in such a manner that the interface conversion you want is provably safe.
Consider an example where it would not be legal to see what I mean. Suppose you have an object which implements IList<Mammal>
. It is in fact a list of mammals. You wish to convert it to IList<Animal>
, figuring "a list of mammals can be used as a list of animals". But you can insert a Snake into a list of animals, which would then attempt to put a snake into a list of mammals, and crash. Lists cannot be covariant safely.
If you can prove to the compiler that your interface is safe for covariance, then C# 4 will let you do this. I'll be posting a detailed description of what the requirements are for safety on my blog in the next couple of weeks.
Not 100% sure what you are shooting for but check out the discussions of covariance and contravariance to see if your scenerio is possible now or if you need to wait for c# 4.0.
https://stackoverflow.com/questions/1078423/c-is-variance-covariance-contravariance-another-word-for-polymorphism
Apologies, the code was at work, but I recreated the error at home:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ArtOfTest.WebAii.Controls.HtmlControls;
namespace iCrawler.Code
{
interface Interface1<T> where T : HtmlControl
{ // May use T for future methods which will be generic in nature eg work with a generic collection of instances of T (not depicted in the method signature below)
void DoStuff();
}
class Child1 : Interface1<ArtOfTest.WebAii.Controls.HtmlControls.HtmlAnchor>
{
public void DoStuff()
{
throw new NotImplementedException();
}
}
class Test
{
public Interface1<HtmlControl> ReturnExperiment()
{
Child1 child1 = new Child1();
return child1;
}
}
}
On the "return child1" line, I get the error below:
Error 1 Cannot implicitly convert type 'iCrawler.Code.Child1' to 'iCrawler.Code.Interface1<ArtOfTest.WebAii.Controls.HtmlControls.HtmlControl>'. An explicit conversion exists (are you missing a cast?) C:\Projects\Current\iCrawler\iCrawler\iCrawler\Code\Interface1.cs 28 20 iCrawler
Also, I'm pretty sure return Child1 (where Child1 is the type not the variable) was perfectly legal?
Thanks
精彩评论