持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第2天,点击查看活动详情
文章标题皮一下,很开心...
言归正传,之所以这样说,是因为我在使用C#处理一些项目中遇到的实际问题中,有一次真遇到一个棘手的问题,坐立不安,无从下手去解决时,翻了半天搜索引擎,一看到dynamic,问题就迎刃而解了!
所以,我取这个名称不过分吧[dog]
其实这个dynamic在C#这样的后端语言中是个编外者,相当于强类型语言中的弱类型,存在即合理吧。
dynamic类型并不是C#语言一开始就有的,说明有需要他的地方,比如说帮我救火的场景中...
救火场景:List类型数据 动态添加属性值
按说这种问题都不是我一个后端该干的活,我数据查询出来,直接甩前端,怎么处理是他的事,他却说我给他的数据有问题,缺少字段信息,让我处理好再给他,不然....奈何他亲戚是领导,罢了罢了,只能把摸鱼时间拿出来帮他处理一下再甩他(屈服理由瞎编的,爱信不信....)
工作场景中具体场景就不说了,差不多相当于List中新增一个动态属性值,这个值是根据T中的其他几个属性值经过一系列计算后得出来的,然后拼接或其他复杂操作后,达到前端拿过去可以直接渲染的效果。
这里用一个简单的例子说明下
比如,给对象中添加一个序号信息(注:真实情况中,这个序号在前端直接可以用数组下标即可,这里仅仅是举例
)
List<User> users = new List<User>();
var order = 0;
foreach (var item in res)
{
var obj = item.ToDynamic();
obj.Order = order++;
users.Add(obj);
}
return users;
//相对简洁一点的写法,借用Select
return res.Select(x =>
{
var r = x.ToDynamic();
r.Order = order++;
return r;
}).ToList();
想想,如果没有dynamic,要后端来处理这种需求还是有点小复杂的
dynamic vs var
var属于临时给变量一个容器,这个容器在变量初始化后即确定了变量的类型!\
而dynamic相当于一个万能容器,不管放什么类型都可以,程序也不会去管它(强类型语言不会对它的类型进行检查抛异常等),只有在程序编译运行时,编译器才会预判它存的到底是个什么玩意,然后进行相应的处理...
变量初始化上的区别问题
先写三个变量
int ab = default;
var sc = default;
dynamic zs = default;
上面代码有问题吗?
是的,真有问题,中间一个会直接报错
因为var 在声明一个变量时必须初始化,否则在C#这种强类型语言中会直接报错处理
而int ab其实已经初始化了因为他已经确定了变量的类型,这个int有默认值,就是 0(基础数据类型,都有默认值,这是最基础的....)
dynamic zs并不会报错,虽然他也没有初始化,也没有确定变量的类型,但是他是在运行中才去解析的,否则程序并不会去判定他的类型,所以没有问题。
初始化问题代码
static void Main(string[] args)
{
List<User> user1 = default;
dynamic user2 = default;
user1.Add(User.GetUser());
user2.Add(User.GetUser());
Console.ReadLine();
}
class User
{
public string Name { get; set; }
public int Age { get; set; }
public static User GetUser()
{
var arr = new string[] { "aaa", "bbb", "ccc", "ddd", "eee" };
var rand = new Random();
return new User { Name = arr[rand.Next(5)], Age = rand.Next(1, 99) };
}
}
猜一下这两种写法有没有问题?为什么?
不出意料,两种写法都有问题,但是报错的点不同,详情看图
报错:对象引用没有设置为一个对象的实例。
报错:无法对一个空引用执行运行时绑定
其实两个报错性质是一样的,只是时机不一样而已!
实例证明,default并不适用与引用类型变量的初始化操作,仅适用于普通的值类型
如下代码操作,会报错吗?
dynamic user = User.GetUser();
user = 666;
Console.WriteLine(user);
并不会报错,正常运行,这C#写的跟js没区别了...
上例:证明dynamic拥有弱类型语言的特性 + 运行时编译最后再确定其类型的,且其类型可动态变化
文末总结
强中自有强中手,再强也需要有弱的一面,不然怎么提现出他的完美。
dynamic就是C#中的弱,有了他的存在,使得c#具备了弱类型特性!