![](/img/trans.png)
[英]Warning "Fields .... is never assigned to and will always have its default value null"
[英]Warning: Field is never assigned to, and will always have its default value null
我有以下信息:
警告:永远不会将字段分配给,并且始终将其默认值设置为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 // ...
};
}
}
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 // ...
};
现在这是代码; 它不仅仅是一个对象模型,显示“ 如果我被编译,我会做什么”。
是的,这似乎是编译器的一个缺点。 它显然无法透视(不包括)表达式。
以下按预期打印“bbc”:
var exp = MyClass.FromMyEntity.Compile();
var mc = exp(new MyEntity { MyProp = "abc"});
Console.WriteLine(mc.MyProp);
我在MyClass上尝试了一些像私有构造函数的技巧,但警告仍然存在。
似乎编译器应用更保守的算法,只检查是否有任何(普通)成员分配给dbMyProp
。
通过使用名称为
dbMyProp
2个不同元素来
dbMyProp
但
MyEntity.MyProp
永远不会写入此处。
这不是编译器中的错误。
PLS。 请参阅Marc Gravell的回答
以下说明不正确。
显示警告,因为在下面的dbMyProp
中将使用未分配的dbMyProp
值。 1. MyClass被实例化。 2.使用实例MyProp
属性。 (这将导致NullReferenceException
)
或者我错过了什么?
你错过了什么。 在lambda表达式中,您创建了MyClass
的新实例并分配了其dbMyProp
字段。 但是您从未在实例方法中分配当前实例的dbMyProp
字段。
检查这个例子:
var instance = new MyClass();
var myProp = instance.MyProp; // BOOM - you never assigned a value to the dbMyProp field
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.