简体   繁体   English

扩展方法如何在后台工作?

[英]How extension methods work in background?

I am just cuirous about behind of extension method mechanism.Some questions and answer appear in my mind. 我只是对扩展方法机制的背后很好奇。一些问题和答案出现在我的脑海中。

MyClass.OrderBy(x=>x.a).OrderBy(x=>x.b);

I was guessing that mechanism was first orderby method works and order them by a member then returns sorted items in IEnumarable interface then next Orderby method of IEnumarable Order them for b paramater.But i am wrong when i look at this linq query. 我猜想机制是第一个orderby方法起作用并由成员对其进行排序,然后在IEnumarable接口中返回已排序的项目,然后在IEnumarable的下一个Orderby方法中返回b参数。但是当我查看此linq查询时,我错了。

MyClass.Orderby(x=>x.a).ThenOrderBy(x=>x.b);

this is slightly different and tells me that i am wrong.Because this is not ordering by a then b and not possible to have such result if i was right.This get me confuse enough... 这有点不同,并告诉我我错了。因为这不是按a然后b排序,如果我是对的就不可能有这样的结果。这让我很困惑...

Similiar structure is possible to write withot extension methods as first query but second is not possible.This prove i am wrong . 类似的结构可以编写withot扩展方法作为第一个查询,但第二个不可能。这证明我是错误的。 Can u explain it ? 你能解释一下吗?

Others have explained very well how extension methods are converted into static methods during compilation so I'm not going to get into that. 其他人很好地解释了在编译过程中如何将扩展方法转换为静态方法,因此我不再赘述。

I think what you are asking though is how OrderBy and ThenBy manage to produce the correct ordering when they are called in sequence, so I am going to try and answer that part of your question. 我想您想问的是,当OrderBy和ThenBy依次被调用时,它们是如何设法产生正确的排序的,所以我将尝试回答问题的这一部分。


The extension method Enumerable.OrderBy returns an IOrderedEnumerable , the concrete class that backs this is an OrderedEnumerable, which internally stores the function that is used to sort the enumerable. 扩展方法Enumerable.OrderBy返回一个IOrderedEnumerable ,支持它的具体类是OrderedEnumerable,该类在内部存储用于对可枚举数进行排序的函数。

When you call ThenBy, you are calling the static Enumerable.ThenBy method and passing the OrderedEnumerable from the output of the first call to OrderBy which creates a second OrderedEnumerable. 调用ThenBy时,您将调用静态Enumerable.ThenBy方法,并将第一次调用的输出中的OrderedEnumerable传递给OrderBy,后者将创建第二个OrderedEnumerable。 This second OrderedEnumerable will contain a reference to the parent OrderedEnumerable that was created the first time. 第二个OrderedEnumerable将包含对第一次创建的父OrderedEnumerable的引用。

So what you have is a OrderedEnumerable that contains a parent OrderedEnumerable, each with the appropriate functions stored for ordering. 因此,您所拥有的是一个OrderedEnumerable,其中包含父OrderedEnumerable,每个父级都存储有用于排序的适当函数。 When you enumerate over it, each OrderedEnumerable first delegates to it's parent, and only uses it's own sorting function when the parent is unable to separate the items being sorted. 枚举时,每个OrderedEnumerable首先将其委托给它的父级,并且仅在父级无法分离要排序的项目时才使用它自己的排序功能。 Obviously, there is no reason why you can't have a chain of several OrderedEnumerables, and it will always be the inner most that gets to call it's sorting function first. 显然,没有理由不能拥有几个OrderedEnumerables的链,并且它始终是最内在的,因此必须首先调用其排序功能。

I drew a quick diagram to try and help explain: 我画了一个简单的图表来尝试帮助解释:

链接文字


I hope that makes sense. 我希望这是有道理的。 I hope I haven't confused the situation there, I think I've pretty much worn out the word 'enumerable'. 我希望我不要混淆那里的情况,我认为我已经很累了“可数”这个词。 If you need more detail you can use reflector to take a look at the what the various methods are doing under the covers. 如果您需要更多细节,可以使用反射器看一下幕后的各种方法。

extension methods are just syntactic sugar and they are replaced by actual static method calls in compiled IL. 扩展方法只是语法糖 ,它们已由编译的IL中的实际静态方法调用替换。

consider this extension method that checks if a string is valid email. 考虑使用此扩展方法检查字符串是否为有效电子邮件。

    public static bool IsEmail(this string email)
    {
        if (email != null)
        {
            return Regex.IsMatch(email, "EmailPattern");
        }

        return false;
    }

in C# I'll call this extension method as below. 在C#中,我将按以下方式调用此扩展方法。

string str = "myname@server.com";
bool isValidEmail = str.IsEmail();

After compilation the call to str.IsEmail() is replaced by IsEmail(str); 编译后,对str.IsEmail()的调用将替换为IsEmail(str);。

In case of, MyClass.OrderBy(x=>xa).OrderBy(x=>xb); 如果是MyClass.OrderBy(x=>xa).OrderBy(x=>xb); each extension method returns the type of instance on which the subsequent extension method is defined. 每个扩展方法都返回实例的类型,在该实例上定义了后续的扩展方法。 This is called chaining of method calls or more appropriately a technique called fluent-interfacing 这称为方法调用的链接,或更恰当地fluent-interfacing称为fluent-interfacing的技术

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM