开发者

Returning generic interface and child implementations from a method

开发者 https://www.devze.com 2022-12-11 13:39 出处:网络
I have a generic interface where the type constraint is an abstract base class. So the implementations may be of different implementations.

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

0

精彩评论

暂无评论...
验证码 换一张
取 消