静态字段需要null实例,非静态字段需要非null实例。参数名称:表达式

时间:2016-04-25 14:38:07

标签: c#

我已经看到了这个错误的可能解决方案,但我只是不明白如何修复我的错误。 我的代码如下所示:

}

/// <summary>
/// Gets our data reader
/// </summary>
/// <param name="reader">The reader to return</param>
/// <returns></returns>
private Func<IDataReader, T> GetReader(IDataReader reader)
{
    Delegate resDelegate;

    // For each field, add to our columns
    List<string> readerColumns = new List<string>();
    for (int index = 0; index < reader.FieldCount; index++)
        readerColumns.Add(reader.GetName(index));

    // Determine the information about the reader
    var readerParam = Expression.Parameter(typeof(IDataReader), "reader");
    var readerGetValue = typeof(IDataReader).GetMethod("GetValue");

    // Create a Constant expression of DBNull.Value to compare values to in reader
    var dbNullValue = typeof(DBNull).GetField("Value");
    var dbNullExp = Expression.Field(Expression.Parameter(typeof(DBNull), "System.DBNull"), dbNullValue);

    // Loop through the properties and create MemberBinding expressions for each property
    List<MemberBinding> memberBindings = new List<MemberBinding>();
    foreach (var prop in typeof(T).GetProperties())
    {
        // Determine the default value of the property
        object defaultValue = null;
        if (prop.PropertyType.IsValueType)
            defaultValue = Activator.CreateInstance(prop.PropertyType);
        else if (prop.PropertyType.Name.ToLower().Equals("string"))
            defaultValue = string.Empty;

        // If the column exists
        if (readerColumns.Contains(prop.Name))
        {

            // Build the Call expression to retrieve the data value from the reader
            var indexExpression = Expression.Constant(reader.GetOrdinal(prop.Name));
            var getValueExp = Expression.Call(readerParam, readerGetValue, new Expression[] { indexExpression });

            // Create the conditional expression to make sure the reader value != DBNull.Value
            var testExp = Expression.NotEqual(dbNullExp, getValueExp);
            var ifTrue = Expression.Convert(getValueExp, prop.PropertyType);
            var ifFalse = Expression.Convert(Expression.Constant(defaultValue), prop.PropertyType);

            // Create the actual Bind expression to bind the value from the reader to the property value
            var mi = typeof(T).GetMember(prop.Name)[0];
            var mb = Expression.Bind(mi, Expression.Condition(testExp, ifTrue, ifFalse));
            memberBindings.Add(mb);
        }
    }

    // Create a MemberInit expression for the item with the member bindings
    var newItem = Expression.New(typeof(T));
    var memberInit = Expression.MemberInit(newItem, memberBindings);

    // Create the lambda expression
    var lambda = Expression.Lambda<Func<IDataReader, T>>(memberInit, new ParameterExpression[] { readerParam });
    resDelegate = lambda.Compile();

    // Return our delegate
    return (Func<IDataReader, T>)resDelegate;
}

正如标题所说,我得到的错误是:

  

静态字段需要空实例,非静态字段需要非空实例。参数名称:表达式

就是这一行:

var dbNullExp = Expression.Field(Expression.Parameter(typeof(DBNull), "System.DBNull"), dbNullValue);

有谁能告诉我为什么我会收到错误以及如何修复它?

2 个答案:

答案 0 :(得分:1)

答案是:

var dbNullExp = Expression.Field(expression: null, type: typeof(DBNull), fieldName: "Value");

因为我使用的是.net 4.5

答案 1 :(得分:0)

您需要使用以下行:

var dbNullExp = 
  Expression.Field(Expression.Parameter(typeof(DBNull), "System.DBNull"), DBNull.value);

这使用dbnull的实例值。静态字段需要null实例。 不要将它与反射一起使用,而只需使用DBNull.value(实例值)