Как заставить реализацию абстрактного метода и возвращающий интерфейс - PullRequest
0 голосов
/ 18 ноября 2018
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
    }
}

Fiddle: https://dotnetfiddle.net/7tA12E

Это надуманный пример для упрощения, например.При использовании SpecificClass я хочу получить SpecificValue автоматически без его приведения.

Абстрактный класс / интерфейс просто для принудительного заключения контракта.На самом деле я не хочу получать интерфейсы в качестве возврата, но то, что возвращает GetValues(), не является специфическим и зависит от каждой реализации (при условии, что они подчиняются контракту)

Я попытался переписать его, используя дженерики, чтобыВы можете сделать

test.GetValues<SpecificValue>(1).Single(), но я все еще верю, что есть способ вернуть SpecificValue без необходимости вводить SpecificValue в Main ()

1 Ответ

0 голосов
/ 18 ноября 2018

Вы можете определить свой абстрактный класс как общий класс следующим образом:

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;
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...