背景:
今天接触到使用Smtp发送邮件的代码,其中一段是关于邮件添加附件的,代码的内容如下:
Attachment data = new Attachment(file, MediaTypeNames.Application.Octet);
// Add time stamp information for the file.
<strong> ContentDisposition disposition = data.ContentDisposition;</strong>
disposition.CreationDate = System.IO.File.GetCreationTime(file);
disposition.ModificationDate = System.IO.File.GetLastWriteTime(file);
disposition.ReadDate = System.IO.File.GetLastAccessTime(file);
// Add the file attachment to this e-mail message.
message.Attachments.Add(data);
其中附件的ContentDisposition属性是个只读属性,所以不能直接对其进行赋值。
我们看到代码中的处理方式:把该只读属性赋值给一个同类型的变量,然后直接对变量进行操作,最后把附件添加到附件集合中。
那么,对只读属性赋予的变量进行属性的修改,同时会改变data.ContentDisposition的值吗?
其实,深入想一下,代码中粗体部分会使得disposition和data.ContentDisposition具有同一个引用。不论由谁对子属性进行修改,都会影响最终的结果。
这样做其实还有一个好处: 就是不必每次都以data.ContentDisposition.CreationDate这样的形式修改属性值,而只要使用disposition.CreateDate这样的形式。
唯一的坏处是:在阅读代码时,这样的形式有时会造成困惑:将一个属性赋值给某个变量,然后只对该变量进行了属性的改变,接着直接把data添加到附件列表中,看着似乎没有对data做任何操作。
---------------
下面我们用一个小示例来模拟上面的情况
首先,我们建一个类ClassA,它包含一个只读属性,我们通过上面的方式去改变它的值
/// <summary>
/// 包含只读属性的类
/// </summary>
public class ClassA
{
private ClassB readonlyB;//需要赋值的属性
public ClassA()
{
readonlyB = new ClassB();
}
/// <summary>
/// 类型为自定义类的只读属性
/// </summary>
public ClassB ReadonlyB
{
get
{
return readonlyB;
}
}
}
ClassB的定义:
/// <summary>
/// 自定义类
/// </summary>
public class ClassB
{
private string m;
public string M
{
get{return m;}
set { m = value; }
}
}
测试代码:
class Program
{
static void Main(string[] args)
{
ClassA parent = new ClassA();
ClassB property2 = parent.ReadonlyB;
Console.Write("Assign Before:");
Console.WriteLine(parent.ReadonlyB.M);
//通过引用变量改变子属性的值
property2.M = "I am an instance of ClassB !";
Console.Write("Assign After:");
Console.WriteLine(parent.ReadonlyB.M);
//判断引用变量和只读属性是否相等
if (property2 == parent.ReadonlyB)
{
Console.WriteLine("property2 and parent.ReadonlyB : The same!");
}
else
{
Console.WriteLine("property2 and parent.ReadonlyB : Different!");
}
Console.ReadLine();
}
}
程序的运行结果:
Assign Before:
Assign After:I am an instance of ClassB !
property2 and parent.ReadonlyB : The same!
总结:
此种给只读属性赋值的方法,只适用于只读属性类型为引用类型(string类型除外),且有子属性的属性;
其实可以直接通过data.ContentDisposition.CreationDate =...的形式进行赋值,而不必采用上面的形式;
这里说的给只读属性赋值,不是直接给其赋值,而是通过设置其子属性的方式改变该只读属性。