c# - 映射不同类型对象的通用方法

标签 c#

我想写一个泛型方法,将 List 映射到新列表,类似于 JS 的 map 方法。然后我会像这样使用这个方法:

var words= new List<string>() { "Kočnica", "druga beseda", "tretja", "izbirni", "vodno bitje" };
List<object> wordsMapped = words.Map(el => new { cela = el, končnica = el.Končnica(5) });

我知道有 Select 方法可以做同样的事情,但我需要编写自己的方法。现在我有这个:

public static IEnumerable<object> SelectMy<T>(this IEnumerable<T> seznam, Predicate<T> predicate)
{
    List<object> ret = new List<object>();

    foreach (var el in seznam)
        ret.Add(predicate(el));

    return ret;
}

我也知道我可以使用 yield return 但我还是不能。我认为问题出在未声明的类型上,编译器无法弄清楚它应该如何映射对象,但我不知道如何解决这个问题。我发现的所有示例和教程都是相同类型的 map 对象。

最佳答案

Linq 的Select 相当于其他函数式语言中的map() 函数。映射函数通常不会被称为 Predicate,IMO - predicate 将是一个可以减少集合的过滤器。

您当然可以包装一个扩展方法,该方法将应用投影以将输入映射到输出(两者都可以是匿名类型):

public static IEnumerable<TO> Map<TI, TO>(this IEnumerable<TI> seznam, 
                                          Func<TI, TO> mapper)
{
    foreach (var item in seznam)
        yield return mapper(item);
}

相当于

public static IEnumerable<TO> Map<TI, TO>(this IEnumerable<TI> seznam, 
                                          Func<TI, TO> mapper)
{
    return seznam.Select(mapper);
}

如果你不想要强返回类型,你可以将输出类型保留为object

public static IEnumerable<object> Map<TI>(this IEnumerable<TI> seznam, Func<TI, object> mapper)
{
   // Same implementation as above

然后这样调用:

var words = new List<string>() { "Kočnica", "druga beseda", "tretja", "izbirni", "vodno bitje" };
var wordsMapped = words.Map(el => new { cela = el, končnica = el.Končnica(5) });

编辑
如果您喜欢动态语言的运行时刺激,您还可以使用 dynamic 代替 object

但是像这样使用dynamic 所以这precludes the using the sugarKončnica 这样的扩展方法 - Končnica 要么需要成为所有使用类型的方法,要么被显式调用,例如

static class MyExtensions
{
    public static int Končnica(this int i, int someInt)
    {
        return i;
    }

    public static Foo Končnica(this Foo f, int someInt)
    {
        return f;
    }

    public static string Končnica(this string s, int someInt)
    {
        return s;
    }
}

然后,如果您输入的所有项目都实现了 Končnica,您可以调用:

var things = new List<object>
{ 
   "Kočnica", "druga beseda", 
    53, 
    new Foo() 
};

var mappedThings = things.Map(el => new 
{ 
     cela = el, 
     končnica = MyExtensions.Končnica(el, 5) 
     // Or el.Končnica(5) IFF it is a method on all types, else run time errors ...
})
.ToList();

关于c# - 映射不同类型对象的通用方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27718652/

相关文章:

c# - WCF - Visual Studio 不会生成 SVC 文件

c# - WOPI 主机实现,试图在 iframe asp.net mvc 中呈现文档

c# - 将 MVC4 站点部署到 Azure 会导致 ExtensionAttribute 异常

c# - 将 Autofac 和 Moqs 与委托(delegate)工厂一起使用

C# 正则表达式可选命名组

c# - MVC : How do I create link on server side

c# - 如何用 IOC 替换 switch 语句以便我可以保持 SOLID 原则

c# - 两个不同的用户可以访问同一个数据库表以插入不同的数据吗?

c# - 如何更改字符串或 double 的文化信息

c# - 你什么时候会使用嵌套锁定?