简体   繁体   中英

Interface with a Generic property

i have a simplified version of the structure like this:

    public class ClassX { }
    public class ClassY { }

    public interface A<T>
    {

        T Data { get; set; }
    }

    public class B : A<ClassY>
    {
        public ClassY Data { get; set; }
    }

    public class C : A<ClassX>
    {
        public ClassX Data { get; set; }
    }   

Then what i want to do is something like this:

    public class Example
    {
        public A Retrieve(string type)  // Point A
        {
            if (type == "B")
            {
                return new B();         // Point B
            }
            else
            {
                return new C();         // Point B
            }
        }
    }

So first issue is I cannot use the return type (Point A) of the method like above because i get this error for the return type: CS0305: Using the generic type 'A<T>' requires 1 type arguments

Then i change the code to this, hoping that setting the generic type as dynamic would solve my problem:

    public class Example
    {
        public A<dynamic> Retrieve(string type)  // Point A
        {
            if (type == "B")
            {
                return new B();         // Point B
            }
            else
            {
                return new C();         // Point B
            }
        }
    }

But with that i get this error for Point B and Point C: CS0266: Cannot implicitly convert type 'Ticketing.XF.B' to 'Ticketing.XF.A<dynamic>'. An explicit conversion exists (are you missing a cast?) CS0266: Cannot implicitly convert type 'Ticketing.XF.B' to 'Ticketing.XF.A<dynamic>'. An explicit conversion exists (are you missing a cast?)

I am stuck at the moment. What would be a clean and proper solution to what i want to do?

This can only be done through the interface for classes. The base interface cannot be generic if you want to use a factory method. Or you need to return a base type such as object

public interface IClass
{
    
}
public class ClassX : IClass { }
public class ClassY : IClass { }

public interface A
{
    IClass Data { get; set; }
}

public class BC<T> : A  where T : class, IClass
{
    public IClass Data { get; set; }

    public T As()
    {
        return Data as T;
    }
}


public class Example
{
    public A Retrieve(string type)  // Point A
    {
        switch (type)
        {
            case "B":
                return new BC<ClassX>();
            default:
                return new BC<ClassY>();
        }
    
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM