惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

美团技术团队
罗磊的独立博客
SecWiki News
SecWiki News
The Register - Security
The Register - Security
The GitHub Blog
The GitHub Blog
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
博客园 - 三生石上(FineUI控件)
S
Schneier on Security
IT之家
IT之家
博客园 - 聂微东
T
The Exploit Database - CXSecurity.com
Recorded Future
Recorded Future
大猫的无限游戏
大猫的无限游戏
Know Your Adversary
Know Your Adversary
Latest news
Latest news
Vercel News
Vercel News
G
GRAHAM CLULEY
D
DataBreaches.Net
D
Darknet – Hacking Tools, Hacker News & Cyber Security
S
SegmentFault 最新的问题
博客园_首页
雷峰网
雷峰网
T
Tenable Blog
Spread Privacy
Spread Privacy
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
酷 壳 – CoolShell
酷 壳 – CoolShell
Cisco Talos Blog
Cisco Talos Blog
V
Visual Studio Blog
J
Java Code Geeks
博客园 - Franky
The Cloudflare Blog
Apple Machine Learning Research
Apple Machine Learning Research
C
CERT Recently Published Vulnerability Notes
T
Threatpost
Google DeepMind News
Google DeepMind News
F
Fortinet All Blogs
P
Privacy International News Feed
T
Threat Research - Cisco Blogs
T
The Blog of Author Tim Ferriss
V
Vulnerabilities – Threatpost
Recent Announcements
Recent Announcements
Blog — PlanetScale
Blog — PlanetScale
Security Latest
Security Latest
U
Unit 42
M
MIT News - Artificial intelligence
Y
Y Combinator Blog
K
Kaspersky official blog
有赞技术团队
有赞技术团队
B
Blog
腾讯CDC

博客园 - 长沙游学者

填坑 Plugin 'mysql_native_password' is not loaded 裁员相关法律知识 自己写了个截图工具 .net操作oracle,一定要用管理员身份运行 visual studio 啊,切记切记,免得报奇怪的错误。 基于 bootstrap 的 vue 分页组件 前端UI框架《Angulr》入门 EF 中 Code First 的数据迁移以及创建视图 AmazeUI(妹子UI)中CSS组件、JS插件、Web组件的区别 Oracle自动备份.bat 最新更新(支持Win10了) 总结一下Android中主题(Theme)的正确玩法 并不优雅 思考:有三扇门,其中一扇门里有奖品,三选一,你选择其中一扇门之后,主持人先不揭晓答案,而是从另外两扇门中排除掉一个没有奖品的门,现在主持人问你,要不要换个门,请问你换还是不换? TableEx 小更新 本地包含的JS 原创的java数据访问框架 java十宗罪 Oracle自动备份.bat 更新 C++ 方块游戏小更新 Oracle自动备份.bat
深入分析结构体——结构体里有属性必须new才能使用?
长沙游学者 · 2013-03-21 · via 博客园 - 长沙游学者

游哥今天遇到了一个关于结构体的神现象。
简单点来说就是:
一个结构体,里面没有属性,可以不new就使用。但在结构体里面写了个属性就必须要new才能使用,这是为什么呢?

直接上代码:

struct Dog    //狗的结构体
{
    public int age;
}
struct Cat   //猫的结构体
{
    public int Age { get; set; }
}
class Program
{
    public static void Main()
    {
        //情况A
        Dog dog1;
        dog1.age = 3;                 //片段1
        Console.WriteLine(dog1.age);  //不出错
        Cat cat1;
        cat1.Age = 3;                 //编译错误
        Console.WriteLine(cat1.Age);  //片段2

        //情况B
        Dog dog2 = new Dog();
        dog2.age = 3;                 //片段3
        Console.WriteLine(dog2.age);  //不出错
        Cat cat2 = new Cat();
        cat2.Age = 3;                 //片段4
        Console.WriteLine(cat2.Age);  //不出错
    }
}

片断4不报错,而片断2则报错。
这里面涉及很多技术细节,你能知道这是为什么吗?


游哥来解答:
1.结构体里只有字段,没有属性。狗类分析:
片断1,不出错。众所周知,结构体可以不new就使用。
片断3,不出错。不new不出错,new了就更不出错了。

2.结构体可以new,也可以不new。new与不new的区别是,new为会每一个成员字段赋一个默认初值(还记得default关键字吗),而不new则不会这么做。
3.任何一个属性,编译器都会自动生成一个与之对应的字段来保存数据,比如这里的Age属性,就会产生出一个_age来为其保存数据。(它可能不叫_age,这不是重点,总之你看不到这个字段,但它确实存在。)
4.了解一下,什么叫数据结构和算法吧。其实有点扯远了,简单来说,可以这么理解,字段就是数据结构,而方法和属性访问器就是算法了。(字段保存数据,而方法和属性访问器对这些数据进行加工计算)。
5.为什么要提出数据结构和算法,我要说的重点是:要调用结构体的算法(各部门请注意,我要来计算了),必须先让所有的数据就就绪(那些字段都赋了初值了吗)。意思就是说,你要调用结构体的任何一个方法或属性访问器之前,必须要给所有的字段赋初始。编译器不会去关心你的算法涉及了哪些字段(编译器不检查你的方法体)。甚至是你的算法没有涉及任何字段的访问,编译器依然要求你将所有的字段都赋上初值才能使用。

6.结构里有属性。猫类分析:
片断2,编译错误。那个隐藏的_age没有赋初值,而你写cat1.Age=3,是调用了Age的set访问器,set访问器是一个算法,你要使用这个算法,必须先将所有字段赋初始,而你的_age没有赋初值,所以就编译错误了。
片断4,不会出错。你在new Cat()时,对_age进行了赋初始操作,所以后面就不出错了。

一点浅见 欢迎批评指正