防爆pressions定义澄清 [英] Expressions definition clarification

查看:202
本文介绍了防爆pressions定义澄清的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

谁能提供什么这里发生一个明确的(和易于理解的)的解释(通常,泛型扩展方法和Ex pression一起):

Could anyone provide a clear (and easy to understand) explanation of what happens here (generally, generics, extension methods and Expression all together):

    public static MvcHtmlString TextBoxFor<TModel, TProperty>
        (this HtmlHelper<TModel> htmlHelper, 
              Expression<Func<TModel, TProperty>> expression)
    {
        return htmlHelper.TextBoxFor(expression, format: null);
    }

和进一步利用在这里:

    Html.TextBoxFor(o => Model.SomeValue)

对于理解最成问题的时刻前pression参数如何在这种条件下的方式。我知道怎么的泛型的工作(通常是他自己),我也知道这是一个的扩展方法的(以及他们如何也可以),但不能赶上如何恩pression再处理(或处理等)的Html.TextBoxFor法(相对来的TModel和Func键的TProperty)。

The most problematic moment for the understanding is the way how Expression parameter works in this conditions. I know how Generics work (generally he he) and I also know that this is an extension method (and how they also work), but can not catch how the expression then handled (or treated etc) in Html.TextBoxFor method (relatively to TModel and TProperty of Func).

提供的code是ASP.NET MVC,但是这不是MVC都:问题是,只是相对前到pressions

感谢您!

编辑:

一些调查后,大多离开了以下问题:什么是在方法定义 TProperty 类参数的作用提供,它是如何影响的方法调用?

After some more investigations, there mostly the following question left: what is the role of TProperty class argument in the method definition provided and how is it influences the method calling?

推荐答案

因此,通过教学学习。这就是我们的生活是什么。他他

问题初步显现澄清一些具体的事情我并不清楚关于code公布,但所有的调查之后,我想,有共享的整体认识我已经得到了有关仿制药的感觉,延伸方法和前pressions(如果它们一起使用)。

The question initially appeared to clarify some specific things I was not clear about the code posted, but after all the investigations, I guess, there is a sense to share the whole understanding I've got about generics, extension methods and expressions (if they are used all together).

这是pretty斯卡里,但是从其他的手还那么漂亮关于C#,当方法的这样一个简单的电话:

That is pretty "scarry", but from other hands is also so beautifully about C#, when such a simple call of the method:

Html.TextBoxFor(model => model.SomeValue)

里面本身隐藏这样的影响力和深的声明,如:

hides inside itself such reach and "deep" declaration, like:

public static class InputExtensions
{
    public static MvcHtmlString TextBoxFor<TModel, TProperty>
        (this HtmlHelper<TModel> htmlHelper, 
         Expression<Func<TModel, TProperty>> expression)
    {
        string format = (string) null;
        return InputExtensions
                .TextBoxFor<TModel, TProperty>(htmlHelper, expression, format);
    }
}

与去实现与ReSharper的使用收到

提供的code反编译的版本。 (其实,我在升级到ReSharper的8后使用定位到/反编译源,但在这里,这不是说说的地方 - 以防万一提)。

The code provided is decompiled version received with "Go to Implementation" with Resharper using. (Actually, I have to use "Navigate To/Decompiled Sources" after upgrading to Resharper 8, but this is not a place to talk about here -- mentioning just in case).

所以,我只是试图解释的整个常规anathomy这样的方法定义的(至少,我知道这件事)。

So, I will just try to explain the whole general "anathomy" of such methods definition (at least, which I know about that).

目标:

要具有一个扩展方法,将延长一定的泛型类,并允许操纵该类数据(请编译时间:具有全智能感知和重构的奖金)上什么课已作为类型参数提到的泛型类已通过依赖性。

To have an extension method which would extend certain generic class and allow to manipulated that class data (in complile time: having all the bonuses of Intellisense and refactoring) dependently on what class has been passed as a type argument to mentioned generic class.

在现实生活中的解释,我会形容为如下:我们有一个类(普通的),这是(一般)适合携带不同的事情如牛奶,白菜,bycicles。但是,当我们定义类似汽车&LT;牛奶及GT; ,那么这车只能携带牛奶。此外,我们认为,该类建筑已经完成(我们不能改变它)。但是,我们也想买一些预告片已为一些汽车的定义,就像CreateATrailer方法,将执行完全一样的产品。我们将能够确定我们需要一个拖车类型的方法是使用产品(牛奶在我们的例子)测量单元(因为这些都是不同的产品不同的:窝,多斤,项目)。在这种情况下,通用的扩展方法(可能的话,使用前pressions)是pretty得心应手。 (这可能是不是一个理想的现实生活中的例子,但是这是我脑子里浮现)。

In real life explanation, I would describe as the following: we have a class Car (generic one), which is (generally) "suitable" for carrying different things like milk, cabbages, bycicles. But when we define something like Car<Milk>, then that car can carry milk only. Also, we consider that that class building already finished (we can not change it). However, we also want to buy some trailer, which would carry exactly the same product as already defined for some car, like having "CreateATrailer" method. The way we would be able to determine the type of a trailer we need is with the product (Milk in our case) measure units (as those are different for different products: litters, kilos, items). In this case, generic extension methods (possibly, with expressions using) are pretty handy. (That might be not an ideal real life example, but this is what came into my mind).

简而言之:

public static class InputExtensions
// ^^ this is where Extension Methods must be placed (inside of a static class)
{
    public static MvcHtmlString TextBoxFor<TModel, TProperty>
    //     ^^ they must also be static    ^^ here must be defined all the generic types
    //                                       which are involved withing the method

        (this HtmlHelper<TModel> htmlHelper, 
    //   ^^ the first parameter must have "this"
    //      this is a parameter which defines the type that the method operates on
    //      so, in this case, it must be some "HtmlHelper<TModel>" class instance

         Expression<Func<TModel, TProperty>> expression)
    //   ^^ the second parameter in the declaration, 
    //      but the first one which appears from caller side (the only one in this very case)
    {
        string format = (string) null;

        return InputExtensions.TextBoxFor<TModel, TProperty>
               (htmlHelper, expression, format);
        // or might also be (dependently if the types 
        //    can be resolved automatically by compiller (the explanation below))
        //    as follows:
        return InputExtensions.TextBoxFor
               (htmlHelper, expression, format);
    }
}

深潜:

我不会重复的泛型扩展方法和< A HREF =htt​​p://msdn.microsoft.com/en-us/library/vstudio/bb397951.aspx相对=nofollow>前pressions(实际上,最初它被称为前pressions树),这是通过谷歌和MSDN广泛使用。但也只是更侧重于如何将大家共同努力。

I won't be duplicating all the detailed explanations of generics, extension methods and expressions (actually, initially it's called "expressions trees"), which are widely available via google and msdn. But will just be more focused on how that would all work together.

public static class InputExtensions

有什么具体有关。只是任何静态类。它的名字大多没有起到任何作用。

There is nothing specific about that. Just any static class. Its name mostly does not play any role.

    public static MvcHtmlString TextBoxFor<TModel, TProperty>

该方法必须是静态的。

The method must be static.

如果我们不使用泛型我们ommit的&lt。但是,如果我们这样做,我们应该指定那里所有的类型(类型模板),它运行时类型将进一步要么由编译器自动解析(依赖性的参数,当你调用这个方法,你会通过),或者必须明确定义,如 someObject.OurExtensionMethod&LT;字符串,整数方​​式&gt;

If we don't use generics we ommit the <...> part completely. But if we do, we should specify there all the Types (Types Templates) which runtime types will be further either resolved by compiler automatically (dependently on parameters you would pass when you call the method), or must be defined explicitly, like someObject.OurExtensionMethod<string, int>.

        (this HtmlHelper<TModel> htmlHelper, 

这个修饰符必须被放在旁边的第一个参数的这是的真正的的迹象,表明该方法是一个扩展

的HtmlHelper 参数将被重新presenting对象,在我们称之为扩展方法。为了便于理解,可以简单地换成@this像名称(这的HtmlHelper&LT;的TModel方式&gt; @this 唯一的区别就是,你显然不具备对类的任何私有成员(S)的访问(如对面是内部的类来扩展)。

htmlHelper parameter will be representing the object, on which we call the extension method. For easier understanding, it might be simply replaced with "@this" name like (this HtmlHelper<TModel> @this. The only difference is just that you obviously don't have an access to any private member(s) of the class (as opposite to being 'inside' of the class to extend).

在这里仅仅是一个普通的泛型类型的原型 - 没有什么特别。这可能是我们想要的东西。即使字符串,即(此字符串@this,

here is just a common generic type prototype -- nothing specific. It could be anything we want. Even string, i.e. (this string @this,.

         Expression<Func<TModel, TProperty>> expression)

这是最棘手的部分,因为我在这里。

所以,如果说扩展方法的部分,这将第一个参数,你会延长一些类时需要提供在其调用该方法。

So, if to speak of extension methods part, this will the first parameter which you would need to provide to the method on its call when extending some class.

至于实施例pression ...我们在这里使用它,以允许用户通过从实例一些值,其中,还可以(通过内部的方法)获得,这是我们提供给他。也就是说, Func键&LT;的TModel,TProperty&GT; (通常是一样的防爆pression&LT; Func键&LT;的TModel,TProperty&GT;&GT; (但不是完全大致相同))意味着,在方法调用,我们为用户提供的一些功能与类型的工作是用于我们的HtmlHelper实例作为输入参数之一。

As for Expression... We use it here to allow a user to pass some value, which further can be obtained (by the method inside) from an instance, which we provide to him. I.e., Func<TModel, TProperty> (which is generally the same as Expression<Func<TModel, TProperty>> (but not completely the same generally)) means, that on the method call we provide the user some ability to work with the type is the one that was used for our HtmlHelper instantiation as a Type parameter.

在换句话说,如果我们创建租车及LT的实例;牛奶&GT; 牛奶办法的TModel 在我们的例子),那么接下来我们提供牛奶类型给调用者,如 Html.TextBoxFor(ourKindOfMilkObject =&GT; ourKindOfMilkObject.MeasureUnits),例如

In other words, if we created an instance of Car<Milk> (Milk means TModel in our case), then then we provide the Milk type to the caller, like Html.TextBoxFor(ourKindOfMilkObject => ourKindOfMilkObject.MeasureUnits), for instance.

(我想,这可能是pretty棘手赶上的人谁没有太多与前pressions熟悉(或者甚至是功能/动作概念),所以我只是希望,如果你读这个你已经知道它是什么(至少基本上))。

在这里最棘手的问题是与 TProperty ,为什么它甚至需要在这里了。

The trickiest question here is with TProperty and why is it even needed in here.

好吧,它是如何工作的:

Ok, how does it work:


  • 首先,必须有某种类型的定义从 Func键返回人参三七川芎提取pression&LT; Func键&GT; )语句。这可能是也只是对象键入如果你真的不关心的那么多:防爆pression&LT; Func键&LT;的TModel,TProperty&GT;&GT ;前pression ;

  • 如果您使用对象而不是(不要使用 TProperty ,但还是把它留在法名称声明),则 TProperty 运行时类型变得没有解决,你应该把它的方法调用明确解决(这显然是,在发展没有意义);

  • 如果你离开它,并有类似的东西作为一个前pression来调用方法时传递: Html.TextBoxFor(型号=&GT; model.SomeValue),编译器解决了 TProperty 键入和你没有指定其在方法调用的类型,否则,你就必须做到以下几点: Html.TextBoxFor&LT; ATypeOfYou​​rModel,串&GT;(型号=&GT; model.SomeValue)字符串 == TProperty 在这种情况下)。

  • 运行时类型之后 TProperty 解决了,你得到尽可能的(这个语法的VisualStudio工具提示(或ReSharper的提示)突出的HtmlHelper的HtmlHelper,防爆pression>前pression)的代替。

  • first of all, there must be some type defined to return from Func (Exspression<Func>) statement. That might be also just object type if you don't really care of that much: Expression<Func<TModel, TProperty>> expression;
  • if you to use object instead (and don't use TProperty, but still leave it in the method name declaration), then TProperty runtime type becomes unresolved, and you should it resolve explicitly on the method call (which is obviously, has no sense in development);
  • if you leave it and have something like that as an expression to pass when calling the method: Html.TextBoxFor(model => model.SomeValue), the compiler resolves the TProperty type and you don't have to specify its type on the method call, otherwise you would have to do the following: Html.TextBoxFor<ATypeOfYourModel, string>(model => model.SomeValue) (string == TProperty in this case).
  • right after the runtime type for TProperty is resolved, you get the syntax highlighting in VisualStudio tooltip (or Resharper hints) as '(this HtmlHelper htmlHelper, Expression> expression)' instead.

最重要的区别就在这里也是我们可以指定哪些适用于使用在 TProperty 类型限制原型(以下简称AND下面一节)。

the most important difference here also is that we can specify limitation of types which are available for using on TProperty Prototype (the "AND:" section below).

关于方法调用,一次。如果我们有我们的对象(例如)如下:

About the method calling, again. If we have our object as follows (for instance):

var html = new HtmlHelper<CustomModel>();
var car = new Car<Milk>();

那么,我们必须调用我们的扩展方法是这样的:

then we must call our extension method this way:

html.TextBoxFor<CustomModel, string>(model => model.SomeValue);
car.AddATrailer<Milk,ParticularMeasureUnitsType>
             (theCarProduct => theCarProduct.MeasureUnits);

但如果所有的泛型类型的模板运行时类型解析(这是在我们的情况(因为是知道与牛奶由它的定义(新车&LT;牛奶&GT;())和前pression 函数功能返回值的类型,也可以从 someValue中类型定义),那么我们简化:

but if all the Generic Types Templates runtime types are resolved (which is in our case (because Car is know that created with Milk by its definition (new Car<Milk>()) and the expression Func return value type is also available from SomeValue type definition), then we simplify:

html.TextBoxFor(model => model.SomeValue);
car.AddATrailer(theCarProduct => theCarProduct.MeasureUnits);

有关泛型非常重要的事情也是我们可以定义类/接口,可用于通用类型的模板要使用的局限性,使用关键字其中,,这样的:

Incredibly important thing about Generics is also that we can define limitations of which class/interface can be used for the Generic Types Templates to use, with using a keyword where, like:

(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression)
        where TModel : CustomModel where some : ParticularValueType

否则,如果我们使用对象而不是TProperty,我们将无法控制我们能够而且我们不能传递到方法(同样的方式,哪些方法来允许扩展方法调用,并在其上​​没有)。

Otherwise, if we use object instead of TProperty, we would not be able to control what we can and what we can not pass into the method (the same way, on which methods to allow the extension methods calling and on which not to).

我相信,仍有可能有一些事情,以改善或更正在这里,所以,请给你的评论上 - 我会很乐意改变话题。

I believe, there are still might be some things to improve or correct in here, so, please give your comments on that -- I will be happy to modify the topic.

这篇关于防爆pressions定义澄清的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆