Reputation: 895
I have a service for Entity1
whose name is Entity1Service
and it contains a method GetBySerial
which is responsible for fetch the appropriate document from the database (I used LiteDb) and returns it:
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();
}
}
}
If I use this method like this:
Entity1Service _entity1Service = new Entity1Service();
dynamic MyDynamic = new System.Dynamic.ExpandoObject();
MyDynamic.Serial = "serial";
var e1 = _entity1Service.GetBySerial(MyDynamic.Serial);
the e1
will be a dynamic variable. But, if I use it like this:
Entity1 e1 = _entity1Service.GetBySerial("serial");
Its type will be Entity1
as expected. I can't figure out why the compiler acts like this.
I face this behavior in a console application, dotnet core v. 2.1 and C# v. 7.3
Update:
Thanks to Jon Skeet, I tried to make a "minimal reproducible example" as he mentioned in a comment. So, during this process, I found that the problem is happened because of a code that I removed from the code for simplicity. So, the problem exactly happens when I pass a dynamic value as the argument to the method. So I edited the first code section.
Upvotes: 1
Views: 214
Reputation: 1501133
This isn't really about var
. That just showed up something that was already going on in your explicitly-typed code. This is about how dynamic typing works. The result of almost any expression involving dynamic
is deemed to be dynamic
.
So in this code:
Entity1Service _entity1Service = new Entity1Service();
dynamic MyDynamic = new System.Dynamic.ExpandoObject();
MyDynamic.Serial = "serial";
var e1 = _entity1Service.GetBySerial(MyDynamic.Serial);
... the compile-time type of MyDynamic.Serial
is dynamic
, and the call to _entity1Service.GetBySerial
is dynamically bound, with a result of dynamic
. When you explicitly type e1
as Entity1
, you're effectively adding a cast after the call.
If you just make sure everything in the expression is statically typed, the result will have the static type you expect. For example, you could cast the argument:
Entity1Service _entity1Service = new Entity1Service();
dynamic MyDynamic = new System.Dynamic.ExpandoObject();
MyDynamic.Serial = "serial";
var e1 = _entity1Service.GetBySerial((string) MyDynamic.Serial);
Or you could use a separate local variable:
Entity1Service _entity1Service = new Entity1Service();
dynamic MyDynamic = new System.Dynamic.ExpandoObject();
MyDynamic.Serial = "serial";
string serial = MyDynamic.Serial;
var e1 = _entity1Service.GetBySerial(serial);
Either way, the _entity1Service.GetBySerial
call is now statically bound - which is almost certainly what you want - and the type of e1
will be Entity1
.
Upvotes: 2