【问题标题】:Creating one helper method for different types via interface c#通过接口 c# 为不同类型创建一个辅助方法
【发布时间】:2019-06-10 09:42:51
【问题描述】:

我需要按相同的值对多个列表进行排序。但是,无论出于何种原因,这些列表包含共享此值的不同类型的对象。我们称之为 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个或更多。

我想我对接口的使用有些基本的了解,但在这件事上任何帮助都将不胜感激。

【问题讨论】:

  • 你传入的“originalList”是什么样的?
  • @Nick 这只是要订购的Child 对象的列表。我也会将其添加到问题中。
  • 你的代码对我来说编译得很好——你运行的是 .Net 4.0 之前的版本(不支持接口变化)?
  • @JonasHøgh 不,4.6.1 是目标框架。
  • 没有办法解决这个问题。如果您的排序操作在所有 IHasChildID 中都是通用的,则无法知道原始输入是 child 类型。除非您的列表很大,否则我不会担心演员表对性能的影响。

标签: c# .net types interface


【解决方案1】:

我不完全确定您的整体用例是什么,但将 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();

【讨论】:

    【解决方案2】:

    可以采用这种方法,例如定义一个接口,然后在所有必需的类或可以查找子 ID 的基类中实现该接口。

    以下是源代码示例。

    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();
        }
    }
    

    如果您想试用此示例并在需要时查看其他选项,请参阅this 链接。

    【讨论】:

    • @Saravanan 感谢您的回答,但正如前面的评论所说 - 我看不出你的代码和我的代码有什么区别。
    猜你喜欢
    • 1970-01-01
    • 2011-06-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-26
    • 1970-01-01
    相关资源
    最近更新 更多