关于访问控制的问题
我运行了http://blog.csdn.net/zhoufoxcn/archive/2009/03/11/3978874.aspx里的代码。(注:我将类MyObject的定义也放到了class Program中)执行到“XmlSerializer serializer = new XmlSerializer(typeof(MyObject)); “ 报“因其保护级别而不可访问 只能处理公共类型”
我发现只要将class program改成public class Program就不会报错了。
但是我不理解为什么要加public,况且不加public时,二进制和soap序列化执行都没有问题。
这个问题我向作者请教,他回复“周金桥 2010-01-11 21:04
这个问题我也不好说什么了,你还是去看访问控制方面的文章吧。”
我是初学者,不理解到底是什么意思. 谁能给我解释一下吗?
谢谢!
--------------------编程问答-------------------- 的确如其所述,
看看public protected private internal的区别及意义吧; --------------------编程问答-------------------- 我了解这四个修饰符的作用:
public: 对任何类和成员都公开, 无限制访问;
protected: 仅仅对该类以及该类的派生类公开;
private: 仅仅对该类公开;
internal: 只能值包含该类的程序集中访问该类(只是单独的项目,而不是整个解决方案);
可是我还是不理解我的问题出在哪里?
我已经将MyObject类的定义放在class program里面,并且设置了public,为什么不能访问? public static void BinarySerialize方法为什么就没有这个问题呢?能否讲得详细些? --------------------编程问答-------------------- up --------------------编程问答-------------------- 我把Myobject的定义也放到了class program里面了。把program定义为public,应该只是为了定义program类的可被访问性吧,这些序列化和反序列化方法以及MyObject定义(已设置为public,成员也都是public的)都在class program里面,我觉得应该和program的访问限制无关,可为什么还要把program也定义为public?我真的不理解为什么。
为什么二进制序列化和SOAP序列化就都不需把program定义为public?
作者的示例代码里并没有把program定义为public,难到他那样设置是可以运行的吗?我这里必须设置public,否则就无法XML序列化 --------------------编程问答--------------------
--------------------编程问答-------------------- 你是我这么写的吗?
/*
* Created by SharpDevelop.
* User: jeri.zhou
* Date: 1/16/2010
* Time: 9:37 AM
*
* To change this template use Tools | Options | Coding | Edit Standard Headers.
*/
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Runtime.Serialization.Formatters;
using System.Runtime.Serialization.Formatters.Binary;
using System.Runtime.Serialization.Formatters.Soap;
using System.Xml.Serialization;
namespace MySerializeDemo
{
[Serializable]
/// <summary>
/// 要序列化的对象
/// 作者:周公
/// 编写时间:2009-03-10
/// </summary>
public class MyObject
{
//[NonSerialized]
private string name;
private DateTime birthday;
private string homePlace;
/// <summary>
/// 出生地
/// </summary>
public string HomePlace
{
get { return homePlace; }
set { homePlace = value; }
}
/// <summary>
/// 生日
/// </summary>
public DateTime Birthday
{
get { return birthday; }
set { birthday = value; }
}
/// <summary>
/// 姓名
/// </summary>
public string Name
{
get { return name; }
set { name = value; }
}
/// <summary>
/// 年龄
/// </summary>
public int Age
{
get { return DateTime.Now.Year - birthday.Year; }
}
/// <summary>
/// override了ToString()方法
/// </summary>
/// <returns></returns>
public override string ToString()
{
return string.Format("姓名:{0},生日:{1},出生地:{2},年龄:{3}",name,birthday,homePlace,Age);
}
}
class Program
{
static void Main(string[] args)
{
MyObject obj = new MyObject();
obj.Birthday = new DateTime(1979, 11, 7);
obj.HomePlace = "湖北";
obj.Name = "周公";
Console.WriteLine("========使用BinaryFormatter类进行序列化和反序列化。====");
BinarySerialize(obj);
BinaryDeserialize("C:\\MyObject.dat");
Console.WriteLine("========使用SoapFormatter类进行序列化和反序列化。====");
SOAPSerialize(obj);
SOAPDeserialize("C:\\MyObject.soap");
Console.WriteLine("========使用XmlSerializer类进行序列化和反序列化。====");
XMLSerialize(obj);
XMLDeserialize("C:\\MyObject.xml");
}
/// <summary>
/// 二进制序列化对象
/// </summary>
/// <param name="obj"></param>
public static void BinarySerialize(MyObject obj)
{
using (FileStream stream = new FileStream("C:\\MyObject.dat", FileMode.Create, FileAccess.Write))
{
BinaryFormatter formater = new BinaryFormatter();
formater.Serialize(stream, obj);
Console.WriteLine("对象已经被序列化。" + obj.ToString());
}
}
/// <summary>
/// 二进制反序列化
/// </summary>
/// <param name="fileName"></param>
public static void BinaryDeserialize(string fileName)
{
using (FileStream stream = new FileStream(fileName, FileMode.Open, FileAccess.Read))
{
BinaryFormatter formater = new BinaryFormatter();
MyObject obj=(MyObject)formater.Deserialize(stream);
Console.WriteLine("对象已经被反序列化。" + obj.ToString());
}
}
/// <summary>
/// 二进制序列化对象
/// </summary>
/// <param name="obj"></param>
public static void SOAPSerialize(MyObject obj)
{
using (FileStream stream = new FileStream("C:\\MyObject.soap", FileMode.Create, FileAccess.Write))
{
SoapFormatter formater = new SoapFormatter();
formater.Serialize(stream, obj);
Console.WriteLine("对象已经被序列化。" + obj.ToString());
}
}
/// <summary>
/// 二进制反序列化
/// </summary>
/// <param name="fileName"></param>
public static void SOAPDeserialize(string fileName)
{
using (FileStream stream = new FileStream(fileName, FileMode.Open, FileAccess.Read))
{
SoapFormatter formater = new SoapFormatter();
MyObject obj = (MyObject)formater.Deserialize(stream);
Console.WriteLine("对象已经被反序列化。" + obj.ToString());
}
}
/// <summary>
/// XML序列化
/// </summary>
/// <param name="obj"></param>
public static void XMLSerialize(MyObject obj)
{
using (FileStream stream = new FileStream("C:\\MyObject.xml", FileMode.Create, FileAccess.Write))
{
XmlSerializer serializer = new XmlSerializer(typeof(MyObject));
serializer.Serialize(stream, obj);
Console.WriteLine("对象已经被序列化。" + obj.ToString());
}
}
/// <summary>
/// XML反序列化
/// </summary>
/// <param name="fileName"></param>
public static void XMLDeserialize(string fileName)
{
using (FileStream stream = new FileStream(fileName, FileMode.Open, FileAccess.Read))
{
XmlSerializer serializer = new XmlSerializer(typeof(MyObject));
MyObject obj = (MyObject)serializer.Deserialize(stream);
Console.WriteLine("对象已经被反序列化。" + obj.ToString());
}
}
}
}
我这么写也没有问题。
你不是在写成这样的吧?
class Program--------------------编程问答-------------------- 是的!
{
//其它代码
class MyObject
{
}
}
你的原代码,在我这里也能正常运行。但是如果将MyObject定义移到class Program里面后,XML序列化就失败了,此时必须将program定义为public.
我就是这点不理解 --------------------编程问答-------------------- up --------------------编程问答-------------------- 顶!(现在有字数限制了)
补充:.NET技术 , C#