Создание одного вспомогательного метода для разных типов через интерфейс c # - PullRequest
0 голосов
/ 16 января 2019

У меня есть требование упорядочить несколько списков по одному значению. Но по какой-то причине эти списки содержат объекты разных типов, которые разделяют это значение. Давайте назовем это ChildID .

Упрощенный код модели будет выглядеть примерно так:

public class Child
{
    public string ChildID { get; set; }
}

public class Parent
{
    public Child Child { get; set; }
}

public class OtherClassID 
{ 
    public int ID { get; set; }
    public string ChildID { get; set; }
}

public class SomeOtherClass
{
    public OtherClassID ID { get; set; }
}

Итак, чтобы избежать дублирования кода, я попробовал это:

public interface IHasChildID
{
    string GetChildID();
}

public class Child : IHasChildID
{
    public string ChildID { get; set; }
    public string GetChildID()
    {
        return ChildID;
    }
}

public class Parent : IHasChildID
{
    public Child Child { get; set; }
    public string GetChildID()
    {
        return Child.ChildID;
    }
}

public class OtherClassID 
{ 
    public int ID { get; set; }
    public string ChildID { get; set; }
}

public class SomeOtherClass : IHasChildID
{
    public OtherClassID ID { get; set; }
    public string GetChildID()
    {
        return ID.ChildID;
    }
}

И когда я создал вспомогательный класс с вспомогательным методом, который принимает интерфейс в качестве параметра, я ожидал, что он будет работать:

public static class ChildOrderHelper
{
    public static IEnumerable<IHasChildID> OrderChildren(IEnumerable<IHasChildID> children)
    {
        var childrenList = children.ToList();
        //do some splitting, ordering and conatenation of lists
        return orderedList;

    }
}

Но при каждом вызове помощника я получаю сообщение об ошибке:

List<Child> originalList = GetChildren(); // whatever
// some lines of code
var orderedList = ChildOrderHelper.OrderChildren(originalList).ToList(); // error

Ошибка CS1503 Аргумент 1: невозможно преобразовать из 'System.Collections.Generic.List ' для 'System.Collections.Generic.List '

И так для каждого вызова помощника, независимо от типа.

Следует отметить, что я привел пример с тремя различными типами, которые имеют это значение и должны быть упорядочены им. В проекте, вероятно, 10 или более.

Полагаю, есть кое-что фундаментальное, что я еще не понимаю в использовании интерфейса, но любая помощь будет полезна в этом вопросе.

Ответы [ 2 ]

0 голосов
/ 16 января 2019

Я не совсем уверен, каков ваш общий вариант использования, но, возможно, было бы полезно сделать метод OrderChildren универсальным, как показано ниже:

public static class ChildOrderHelper
{
  public static IEnumerable<T> OrderChildren<T>(IEnumerable<T> children) where T : IHasChildID
  {
    var childrenList = children.ToList();
    //just a simple example of what I'm guessing the method could do...
    return childrenList.OrderBy(c => c.GetChildID()).ToList();
  }
}

И назовите это следующим образом:

List<Child> originalList = GetChildren();
List<Child> orderedList = ChildOrderHelper.OrderChildren<Child>(originalList).ToList();
0 голосов
/ 16 января 2019

Этот подход можно использовать, как определение интерфейса и его реализацию во всех необходимых классах или базовом классе, который может искать дочерний идентификатор.

Ниже приведен пример исходного кода.

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

public class Program
{
    public static void Main()
    {
        var parents = new List<Parent>();
        parents.Add(new Parent{ChildId = "123"});
        parents.Add(new Parent{ChildId = "321"});
        parents.Add(new Parent{ChildId = "456"});

        var result = ChildHelpers.OrderChildren(parents);

        foreach(var res in result) {
            Console.WriteLine(res.ChildId);
        }
        Console.WriteLine("Hello World");
    }
}

public interface IChild {
    string ChildId {get;set;}
}

public class Child : IChild {
    public string Name {get;set;}
    public string ChildId {get;set;}
}

public class Parent : IChild {
    public Parent() {
        child = new Child();
    }
    public Child child {get;set;}
    public string ChildId {
        get{
            return child.ChildId;
        }
        set{
            child.ChildId = value;
        }
    }
}

public class AnotherChild : IChild {
    public string Description{get;set;}
    public string ChildId {get;set;}
}

public static class ChildHelpers {
    public static IEnumerable<IChild> OrderChildren(IEnumerable<IChild> children)
    {
        return children.OrderBy(c=>c.ChildId).AsEnumerable();
    }
}

Если вы хотите обойти этот пример и посмотреть другие варианты, если это необходимо, обратитесь к этой ссылке.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...