阅读目录:
一. 为什么是它们三个
二. 当需求发生变动时,非IoC遭遇到的困境
三. 使用IoC彻底解决问题
四. 总结
一. 为什么是它们三个?
拿这三者比较的原因是它们在使用的时候非常相似。你可以用它们声明的变量赋任何类型的值。
看看下面的示例:
object b = 1;
dynamic c = 1;
你还可以使用关键字为它们赋上更加复杂的类型
object b = new string[]{"1"};
dynamic c = new string[]{"1"};
二. 能够任意赋值的原因
上面的例子中,看起来三者非常相似,但是背后的原理却是非常不同。
var是C# 3中引入的,其实它仅仅只是一个语法糖. var本身并不是一种类型, 其它两者object和dynamic是类型。
var声明的变量在赋值的那一刻,就已经决定了它是什么类型。
所以如果你这样使用,就会有编译错误:
a = "Test";
object之所以能够被赋值为任意类型的原因,其实都知道,因为所有的类型都派生自object. 所以它可以赋值为任何类型:
a = "Test";
那么dynamic呢?
它是C#引入的新类型,它的特点是申明为dynamic类型的变量,不是在编译时候确定实际类型的, 而是在运行时。
所以下面的代码是能够通过编译的,但是会在运行时报错:
a++;
上面代码内部处理的过程是怎样的呢?
首先, dynamic类型赋值为字符串"test", 运行++操作的时候,.net会去寻找当前的赋值类型string中是否支持++操作,发现不支持,出现异常。
所以,如果这样修改一下,就可以让代码正常运行起来
a = 1;
a++;
三. dynamic的用法
1 直接使用该类型,可以非常方便的插入属性, 方法
{
dynamic person = new System.Dynamic.ExpandoObject();
person.Name = "cary";
person.Age = 25;
person.ShowDescription = new Func<string>(() => person.Name + person.Age);
Console.WriteLine(person.Name + person.Age + person.ShowDescription());
Console.ReadLine();
}
2 枚举所有成员
{
Console.WriteLine(property.Key + ": " + property.Value);
}
3 简化反射
常用的处理反射的例子:
Type calcType = calc.GetType();
object res = calcType.InvokeMember( "Add", BindingFlags.InvokeMethod, null, new object[] { 10, 20 });
int sum = Convert.ToInt32(res);
使用dynamic之后:
int sum = calc.Add(10, 20);
四,使用dynamic的注意事项
有了dynamic,.net就以及有了动态类型的优势,但是由于对于dynamic类型的所有操作,都是在运行时确定的,所有错误无法在编译时候出现,使用的时候,就需要非常小心。
因为dynamic是类型,所以如果函数接受的是确定类型的参数,是不能传入dynamic类型的,这样会有编译错误。比如:
return a + b;
}
dynamic test1 = 1;
dynamic test2 = 2;
Add(test1, test2);
另外,在我们自己在写函数时,最好不要将dynamic类型作为函数的参数,这就像是使用object作为函数参数一样,会为程序的维护带来后续的麻烦。
没有人能够确定使用者传入的是什么,而且编译时候不会有问题。如果错误出现在运行时,就有可能是灾难。
本文链接:http://www.cnblogs.com/JustRun1983/p/3163350.html,转载请注明。
在Android中一共提供了5种数据存储方式,分别为:
(1)Files:通过FileInputStream和FileOutputStream对文件进行操作。具体使用方法可以参阅博文《Android学习笔记34:使用文件存储数据》。
(2)Shared Preferences:常用来存储键值对形式的数据,对系统配置信息进行保存。具体使用方法可以参阅博文《Android学习笔记35:使用Shared Preferences方式存储数据》。
(3)Content Providers:数据共享,用于应用程序之间数据的访问。
(4)SQLite:Android自带的轻量级关系型数据库,支持SQL语言,用来存储大量的数据,并且能够对数据进行使用、更新、维护等操作。具体使用方法可以参阅博文《Android学习笔记36:使用SQLite方式存储数据》。
(5)Network:通过网络来存储和获取数据。
本篇博文介绍第三种方式,通过Content Providers实现应用程序之间的数据共享。
1.Content Providers简介
在Android系统中,不存在一个公共的数据存储区供所有的应用程序访问,也就是说数据在各个应用程序中是私有的。那么,如何在一个应用程序中访问另一个应用程序中的数据,实现应用程序之间的数据共享呢?
当然,你可以通过《Android学习笔记34:使用文件存储数据》一文中讲到的设置openFileOutput()方法中的第二个参数mode为Context.MODE_WORLD_READABLE和Context.MODE_WORLD_WRITEABLE,让别的应用程序可以读写该应用程序中的文件。但是,使用这种方式的弊端也是显而易见的,不仅需要知道该文件的存储路径,而且会将该文件内容完全的暴露出去,对于内容提供者和内容访问者来说都是不方便和不安全的。
为此,Android系统提供了Content Providers,用以方便安全的实现应用程序间的数据共享。
1.1ContentResolver
所有的Content Providers都会实现一些共同的接口,包括数据的查询、添加、更改和删除。在应用程序中,我们可以通过使用getContentResolver()方法来取得一个ContentResolver对象,然后就可以通过这个ContentResolver对象来操作你需要的Content Provider了。ContentResolver类提供的用来操作Content Provider的方法主要有insert()、delete()、update()和query()。
通常,对于开发者而言,并不需要同Content Provider对象直接打交道。系统运行时,会将所有的ContentProvider对象实例化,对于每一种类型的ContentProvider只有一个实例。这个实例可以与在不同的程序或进程中的多个ContentResolver对象进行通信。而这些进程间的交互则是由ContentResolver和ContentProvider类进行处理的。
对于Content Providers而言,最重要的就是数据存储结构和URI。
没有评论:
发表评论