必须初始化隐式类型的局部变量

时间:2014-03-07 08:02:02

标签: linq linq-expressions

我正在进行列排序,并且存在编译时错误:

public static class Helper
{
    public static IQueryable<T> FilterForColumn<T>(this IQueryable<T> queryable, string colName, string searchText)
    {
        if (colName != null && searchText != null)
    {
        var parameter = Expression.Parameter(typeof(T), "m");
        var propertyExpression = Expression.Property(parameter, colName);
        System.Linq.Expressions.ConstantExpression searchExpression = null;
        System.Reflection.MethodInfo containsMethod = null;
        switch (colName)
        {
            case "Title":
            case "Publisher":
            case "ToUser":
            case "CategoryName":
            case "StatusName":
            case "GroupName":
            case "FileSize":
                searchExpression = Expression.Constant(searchText);
                containsMethod = typeof(string).GetMethod("Contains", new[] { typeof(string) });
                break;
            case "PublishDate":
                searchExpression = Expression.Constant(DateTime.ParseExact(searchText,"dd/MM/yyyy",null));
                containsMethod = typeof(string).GetMethod("Equals", new[] { typeof(DateTime) });
                break;
        }
        var body = Expression.Call(propertyExpression, containsMethod, searchExpression);
        var predicate = Expression.Lambda<Func<T, bool>>(body, new[] { parameter });
        return queryable.Where(predicate);
    }
        else
        {
            return queryable;
        }
    }
}

该错误意味着什么。我只是想知道刚才说的是什么错误。 请帮助我发生的事情...

----------------------------------更新--------- -------------------------------

将PublishDate案例更改为:

case "PublishDate":
                    searchExpression = Expression.Constant(DateTime.ParseExact(searchText,"dd/MM/yyyy",null));
                    containsMethod = typeof(string).GetMethod("Equals", new[] { typeof(DateTime) });
                    break;

我遇到这样的错误:

Server Error in '/EasyWeb' Application.
Method 'Boolean Equals(System.Object)' is not defined for type 'System.Nullable`1[System.DateTime]'
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Exception Details: System.ArgumentException: Method 'Boolean Equals(System.Object)' is not defined for type 'System.Nullable`1[System.DateTime]'

Source Error:


Line 39:                     break;
Line 40:             }
Line 41:             var body = Expression.Call(propertyExpression, containsMethod, searchExpression);
Line 42:             var predicate = Expression.Lambda<Func<T, bool>>(body, new[] { parameter });
Line 43:             return queryable.Where(predicate);


Source File: f:\EasyWeb\App_Code\Helper.cs    Line: 41

Stack Trace:


[ArgumentException: Method 'Boolean Equals(System.Object)' is not defined for type 'System.Nullable`1[System.DateTime]']
   System.Linq.Expressions.Expression.ValidateCallInstanceType(Type instanceType, MethodInfo method) +763804
   System.Linq.Expressions.Expression.ValidateCallArgs(Expression instance, MethodInfo method, ReadOnlyCollection`1& arguments) +71
   System.Linq.Expressions.Expression.Call(Expression instance, MethodInfo method, IEnumerable`1 arguments) +46
   System.Linq.Expressions.Expression.Call(Expression instance, MethodInfo method, Expression[] arguments) +31
   Helper.FilterForColumn(IQueryable`1 queryable, String colName, String searchText) in f:\EasyWeb\App_Code\Helper.cs:41
   Admin_Post_History.FillGrid(String CommandName, String ColumnName, String SearchText) in f:\EasyWeb\Admin\Post_History.aspx.cs:63
   Admin_Post_History.btnsearch_Click(Object sender, EventArgs e) in f:\EasyWeb\Admin\Post_History.aspx.cs:2414
   System.Web.UI.WebControls.Button.OnClick(EventArgs e) +111
   System.Web.UI.WebControls.Button.RaisePostBackEvent(String eventArgument) +110
   System.Web.UI.WebControls.Button.System.Web.UI.IPostBackEventHandler.RaisePostBackEvent(String eventArgument) +10
   System.Web.UI.Page.RaisePostBackEvent(IPostBackEventHandler sourceControl, String eventArgument) +13
   System.Web.UI.Page.RaisePostBackEvent(NameValueCollection postData) +36
   System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +1565

2 个答案:

答案 0 :(得分:4)

来自MSDN Implicitly Typed Local Variables

  

隐式类型局部变量中的局部变量声明符   声明受以下限制:

     
      
  • 声明者必须包含初始化程序。
  •   

此限制也在C#规范8.5.1局部变量声明中描述。局部变量声明如下:

local-variable-declaration:  
   local-variable-type   local-variable-declarators

local-variable-type:
   type
   var

local-variable-declarators:
   local-variable-declarator
   local-variable-declarators   ,   local-variable-declarator

local-variable-declarator:
   identifier
   identifier   =   local-variable-initializer

local-variable-initializer:
   expression
   array-initializer

其中局部变量类型是类型名称或var。如果范围中没有名为var的类型,则编译器将此声明视为隐式类型的局部变量声明。这里有区别 - 使用命名类型局部变量初始化程序是可选的,声明可以包含多个变量声明符,即您可以编写int x;int x, y;。但对于隐式类型变量,定义了限制:

  • local-variable-declaration不能包含多个local-variable-declarators。
  • local-variable-declarator必须包含local-variable-initializer。
  • local-variable-initializer必须是表达式。
  • 初始化表达式必须具有编译时类型。
  • 初始化表达式不能引用声明的变量 本身

即。隐式类型的局部变量声明看起来不像var x;var x, y;


因此,在您的情况下初始化程序不包含在变量声明中,那么您只能为变量使用命名类型声明

MethodInfo containsMethod;

答案 1 :(得分:4)

var containsMethod = <XYZ>;

告诉编译器 - “嘿,你,分析表达式<XYZ>,无论你为此推断出什么类型,都要把它作为containsMethod变量的类型。”

但在你的情况下,你没有给它任何表达来分析。所以你不能使用隐式类型变量(var),你必须告诉它{(1}}是什么类型。

所以:

containsMethod

也许