如何强制实现抽象方法和返回接口

时间:2018-11-18 07:02:38

标签: c# generics interface

using System;
using System.Collections.Generic;
using System.Linq;

public interface IValue
{
    int Id { get;}
}

public class SpecificValue : IValue
{
    public int Id { get { return 3; } }
    public string Val { get; set; } 
}

public abstract class MustImplement
{
    public abstract IEnumerable<IValue> GetValues(int number);
}

public class SpecificClass : MustImplement
{
    public override IEnumerable<IValue> GetValues(int number)
    {
        var rv = new List<SpecificValue>();
        rv.Add(new SpecificValue()
        {Val = number + "Test"});
        return rv;
    }
}

public class Program
{
    public static void Main()
    {
        var test = new SpecificClass();
        var values = test.GetValues(1).Single();
        Console.WriteLine(values.Id);
        //Console.WriteLine(values.Val); // This doesnt work

        var values2 = test.GetValues(1).Single() as SpecificValue;
        Console.WriteLine(values2.Id);
        Console.WriteLine(values2.Val); // This works but I dont want to have to cast. values2 is also potentially null now and that's annoying
    }
}

提琴:https://dotnetfiddle.net/7tA12E

这是一个简化的示例,例如。使用SpecificClass时,我想自动获取SpecificValue而不必强制转换。

抽象类/接口就在其中以强制签订合同。我并不想真正获得接口作为返回,但是GetValues()返回的返回不是特定的,并且取决于每个实现(只要它们遵守合同)

我试图使用泛型重写它,以便您可以

test.GetValues<SpecificValue>(1).Single(),但我仍然相信有一种无需在Main()中键入SpecificValue即可返回SpecificValue的方法

1 个答案:

答案 0 :(得分:2)

您可以将抽象类定义为通用类,如下所示:

public abstract class MustImplement<T> where T: IValue
{
    public abstract IEnumerable<T> GetValues(int number);
}

public class SpecificClass : MustImplement<SpecificValue>
{
    public override IEnumerable<SpecificValue> GetValues(int number)
    {
        var rv = new List<SpecificValue>();
        rv.Add(new SpecificValue()
        {Val = number + "Test"});
        return rv;
    }
}