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);
}