[英]var keyword can change a variable type to dynamic?
我有一个服务Entity1
他的名字是Entity1Service
,它包含一个方法GetBySerial
它负责从数据库(我用取合适的文档LiteDb ),并返回它:
public class Entity1Service
{
private readonly LiteCollection<Entity1> _entity1Collection;
private readonly LiteDatabase _db;
public Entity1Service()
{
_db = new LiteDatabase(Constants.DbFileName);
_entity1Collection = _db.GetCollection<Entity1>(nameof(Entity1));
}
public Entity1 GetBySerial(string serial)
{
var q = Query.EQ(nameof(Entity1.Serial), serial);
lock (Constants.DbLockObj)
{
return _entity1Collection.Find(q).SingleOrDefault();
}
}
}
如果我像这样使用这种方法:
Entity1Service _entity1Service = new Entity1Service();
dynamic MyDynamic = new System.Dynamic.ExpandoObject();
MyDynamic.Serial = "serial";
var e1 = _entity1Service.GetBySerial(MyDynamic.Serial);
e1
将是一个动态变量。 但是,如果我像这样使用它:
Entity1 e1 = _entity1Service.GetBySerial("serial");
正如预期的那样,它的类型将是Entity1
。 我不明白为什么编译器会这样。
我在控制台应用程序 dotnet core v. 2.1 和 C# v. 7.3 中遇到这种行为
更新:
感谢 Jon Skeet,正如他在评论中提到的那样,我尝试制作一个“最小可重复示例”。 所以,在这个过程中,我发现问题的发生是因为为了简单起见,我从代码中删除了一段代码。 因此,当我将动态值作为参数传递给方法时,问题就会发生。 所以我编辑了第一个代码部分。
这不是真的关于var
。 这只是显示了在您的显式类型代码中已经发生的事情。 这是关于动态类型的工作原理。 几乎任何涉及dynamic
表达式的结果都被认为是dynamic
。
所以在这段代码中:
Entity1Service _entity1Service = new Entity1Service();
dynamic MyDynamic = new System.Dynamic.ExpandoObject();
MyDynamic.Serial = "serial";
var e1 = _entity1Service.GetBySerial(MyDynamic.Serial);
... MyDynamic.Serial
的编译时类型是dynamic
,对_entity1Service.GetBySerial
的调用是动态绑定的,结果是dynamic
。 当您将e1
显式键入为Entity1
,您实际上是在调用后添加了一个演员表。
如果您只是确保表达式中的所有内容都是静态类型的,那么结果将具有您期望的静态类型。 例如,您可以转换参数:
Entity1Service _entity1Service = new Entity1Service();
dynamic MyDynamic = new System.Dynamic.ExpandoObject();
MyDynamic.Serial = "serial";
var e1 = _entity1Service.GetBySerial((string) MyDynamic.Serial);
或者您可以使用单独的局部变量:
Entity1Service _entity1Service = new Entity1Service();
dynamic MyDynamic = new System.Dynamic.ExpandoObject();
MyDynamic.Serial = "serial";
string serial = MyDynamic.Serial;
var e1 = _entity1Service.GetBySerial(serial);
无论哪种方式, _entity1Service.GetBySerial
调用现在都是静态绑定的——这几乎肯定是你想要的——并且e1
的类型将是Entity1
。
var的简要历史;
var是在C#3.0中引入的。 其目的是“隐式”告诉编译器变量的类型。 这意味着变量类型由编译器在编译时确定。
动态关键字更多地用于语言间字段信息。 不应该这样。 它就像对象类型,无需强制转换。
如果不看代码,很难分辨。 它更多的是猜测。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.