Eval在C#是用来绑定表达式的
通过下面代码,我们来说明Eval的设计思路
首先检查当前页面是否存在,如果不存在检查其继承的页是否存在,如果不存在报异常。
然后开始调用DataBinder.Eval方法进行数据的绑定。
在数据绑定之前,可以看到其有两个变量一个是GetDataItem()以及expression
首先检查表达式是否为空,在这里同是同null和长度计算的。
接着检查容器是否为空。
然后对表达式进行分解变成数组
然后对容器的属性值和表达式进行循环,(i < expressionParts.Length) && (propertyValue != null);这种写法真是不错。
PropertyDescriptor descriptor = GetPropertiesFromCache(container).Find(propName, true);
在下一步,然后就是返回其属性值了,通过得到查找容器范存找到改属性,然后赋值,这样过程就完成啦。
protected internal object Eval(string expression) { this.CheckPageExists(); return DataBinder.Eval(this.Page.GetDataItem(), expression); } private void CheckPageExists() { if (this.Page == null) { throw new InvalidOperationException(SR.GetString("TemplateControl_DataBindingRequiresPage")); } } [Bindable(false), WebSysDescription("Control_Page"), Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public virtual Page Page { get { if ((this._page == null) && (this.Parent != null)) { this._page = this.Parent.Page; } return this._page; } set { if (this.OwnerControl != null) { throw new InvalidOperationException(); } this._page = value; } } public static object Eval(object container, string expression) { if (expression == null) { throw new ArgumentNullException("expression"); } expression = expression.Trim(); if (expression.Length == 0) { throw new ArgumentNullException("expression"); } if (container == null) { return null; } string[] expressionParts = expression.Split(expressionPartSeparator); return Eval(container, expressionParts); } [TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")] public string[] Split(params char[] separator) { return this.SplitInternal(separator, 0x7fffffff, StringSplitOptions.None); } private static object Eval(object container, string[] expressionParts) { object propertyValue = container; for (int i = 0; (i < expressionParts.Length) && (propertyValue != null); i++) { string propName = expressionParts[i]; if (propName.IndexOfAny(indexExprStartChars) < 0) { propertyValue = GetPropertyValue(propertyValue, propName); } else { propertyValue = GetIndexedPropertyValue(propertyValue, propName); } } return propertyValue; } public static object GetPropertyValue(object container, string propName) { if (container == null) { throw new ArgumentNullException("container"); } if (string.IsNullOrEmpty(propName)) { throw new ArgumentNullException("propName"); } PropertyDescriptor descriptor = GetPropertiesFromCache(container).Find(propName, true); if (descriptor == null) { throw new HttpException(SR.GetString("DataBinder_Prop_Not_Found", new object[] { container.GetType().FullName, propName })); } return descriptor.GetValue(container); } public static object GetPropertyValue(object container, string propName) { if (container == null) { throw new ArgumentNullException("container"); } if (string.IsNullOrEmpty(propName)) { throw new ArgumentNullException("propName"); } PropertyDescriptor descriptor = GetPropertiesFromCache(container).Find(propName, true); if (descriptor == null) { throw new HttpException(SR.GetString("DataBinder_Prop_Not_Found", new object[] { container.GetType().FullName, propName })); } return descriptor.GetValue(container); }