安全转换功能

时间:2016-10-21 14:43:43

标签: c#

有人可以解释一下这段代码,特别是我不确定参数的泛型函数是如何工作的:

result.Notes= orderInfo.Notes.SafeConvert(x => (Communication.OrderNotes)x);            

public static TOut[] SafeConvert<TIn, TOut>(
        this TIn[] input,
        Func<TIn, TOut> converter)
    {
        if (input == null)
        {
            return null;
        }

        return input
            .Where(i => i != null)
            .Select(converter)
            .ToArray();
    }

2 个答案:

答案 0 :(得分:1)

SafeConvert是一个通用的extension method。当在某种类型的数组(在这种情况下可能是注释?)上调用该方法时,会隐式添加第一个参数(泛型类型TIn的数组)。该方法还需要一个函数作为参数。此函数必须采用TIn类型的实例并返回TOut实例。因此,您将在某种类型的数组上调用此方法,提供lambda表达式或委托函数,它将返回您提供的函数返回的任何类型的数组。它通过使用Linq过滤掉空值,通过该方法运行数组中的每个项目,然后将这些项目的枚举作为数组返回来实现此目的。

在你给出的实现中,它接受“orderInfo”的“注释”并明确地将它们转换为“CommunicationOrderNotes”。

这是您可以调用该方法的另一种方法。

var decimals = new [] {5,3,2,1} .SafeConvert(someInt =&gt;(decimal)someInt);

答案 1 :(得分:0)

这就是所谓的extension method。它是一个静态函数,允许您在不修改原始代码的情况下向类型“添加”方法。它有点类似于Decorator Pattern但是controversy关于它是否实际上是该特定模式的实现。

“幕后”至少,扩展方法只是用于调用静态方法的“语法糖”,但是你可以将它们称为扩展对象的实例方法(在本例中为数组)。

<TIn, TOut>部分意味着TInTOut是您尚未指定的某种类型(但您打算指定他们实际的内容当你去上课时)。要理解这个的目的,想一下链接列表 - 实际上,整数链接列表的实现与字符串链接列表的代码没有任何不同,所以你希望它是你的情况可以创建单个类,并在以后指定您需要整数列表或字符串列表或其他任何内容。你肯定想要为每一种可能的对象类型创建一个实现 - 这需要大量的冗余代码。

现在,对于LINQ查询:

return input
        .Where(i => i != null)
        .Select(converter)
        .ToArray();

LINQ(语言集成查询)是一种使用单一语法查询不同类型集合的机制。例如,您可以使用它来查询.NET集合(就像他们在这里一样),XML documentsdatabases

LINQ查询采用某种anonymous function并以某种方式将运算符应用于集合(见下文)。

完成此查询;

.Where(i => i != null)

顾名思义,Where应用过滤器。应用于集合时,它将返回第二个集合,其中第一个集合的所有元素都与筛选条件匹配。在

i => i != null

bit是充当过滤器的匿名函数。基本上,这就是说“给我一个集合,其中包含非空的所有数组成员。”

Select方法将变换应用于集合的每个元素,并将结果作为第二个集合返回。在这种情况下,您将传入的任何变换作为参数应用于方法。

将代码视为数据可能听起来有些奇怪,但这在其他一些语言(如F#,Lisp和Scala)中实际上非常常见。 (“引擎盖下”,C#以面向对象的方式实现这种行为,但效果是一样的。)

这个函数的基本思想是,它将一个类型的数组转换为第二个类型的数组,过滤掉所有的空引用。