警告:永远不会将字段分配给,并且始终将其默认值设置为null

时间:2012-09-21 09:05:17

标签: c# compiler-construction compiler-warnings

我收到以下消息:

  

警告:永远不会将字段分配给,并始终将其默认值设置为null。

我的代码看起来像(简化,无用):

public class MyEntity
{
    // ...
    public string MyProp { get; set; }
}

public class MyClass
{
    string dbMyProp;

    public string MyProp { get { return dbMyProp.Replace("a", "b"); } }

    public static readonly Expression<Func<MyEntity, MyClass>> FromMyEntity = e => new MyClass
    {
        dbMyProp = e.MyProp // ...
    };
}

我认为这个消息不是真的。

它是C#编译器中的错误还是我错过了什么?

更新该字段为dbMyProp。它已经过简化,但仍会产生此警告。

UPDATE2 以下代码不会产生此类警告:

public class MyClass2
{
    string dbMyProp;

    public string MyProp { get { return dbMyProp.Replace("a", "b"); } }

    public static MyClass2 FromMyEntity(MyEntity e)
    {
        return new MyClass2 
        {
            dbMyProp = e.MyProp // ...
        };
    }
}

4 个答案:

答案 0 :(得分:5)

Expression 不是代码。这是意图;所以在编译器级别,确实可以说没有代码实际上会分配该字段。有一个MemberAssignment(来自Expression.Bind),但这是无关的。

如果编译表达式,那只能通过实际的字段赋值。这将是运行时的反射,编译器不会尝试检测它。

以下是实际在编译时的内容:

static MyClass()
{
    ParameterExpression CS$0$0000;
    FromMyEntity = Expression.Lambda<Func<MyEntity, MyClass>>(
      Expression.MemberInit(
        Expression.New(
          (ConstructorInfo)methodof(MyClass..ctor),
          new Expression[0]
        ),
        new MemberBinding[] {
          Expression.Bind(
            fieldof(MyClass.dbMyProp),
            Expression.Property(
              CS$0$0000 = Expression.Parameter(typeof(MyEntity), "e"),
              (MethodInfo)methodof(MyEntity.get_MyProp)
            )
          )
        }
      ),
      new ParameterExpression[] {
        CS$0$0000
      }
    );
}

注意不是对字段的任何分配;只使用虚构的fieldof运算符(意​​思是:它直接嵌入字段句柄 - 它不使用名称的string

按照同样的逻辑,如果我们将其作为委托,警告就会消失

public static readonly Func<MyEntity, MyClass> FromMyEntity = e => new MyClass
{
    dbMyProp = e.MyProp // ...
};

现在这个代码;它不仅仅是一个对象模型,显示“这是

答案 1 :(得分:1)

是的,这似乎是编译器的一个缺点。它显然无法看透(不包括)表达 以下按预期打印“bbc”:

var exp = MyClass.FromMyEntity.Compile();
var mc = exp(new MyEntity { MyProp = "abc"});
Console.WriteLine(mc.MyProp);

我在MyClass上尝试了一些像私有构造函数的技巧,但警告仍然存在。

编译器似乎应用了更保守的算法,只检查是否有任何(普通)成员分配给dbMyProp


<击> 您通过使用名称为dbMyProp的2个不同元素来解决问题,但MyEntity.MyProp永远不会写入此处。

答案 2 :(得分:0)

这不是编译器中的错误。

PLS。通过Marc Gravell

查看答案

以下说明不正确。


显示警告,因为在下面的场景中将使用未分配的dbMyProp值。 1. MyClass被实例化。 2.调用实例MyProp属性。 (这将导致NullReferenceException

答案 3 :(得分:0)

  

或者我错过了什么?

你错过了什么。在lambda表达式中,您创建了MyClass new 实例并分配了其dbMyProp字段。但您从未在实例方法中分配当前实例的dbMyProp字段。

检查这个例子:

var instance = new MyClass();
var myProp = instance.MyProp; // BOOM - you never assigned a value to the dbMyProp field