P.B*_*key 17 c# value-type reference-type
我理解,在引用类型上使用值类型的决定应该基于语义,而不是性能.我不明白为什么值类型可以合法地包含引用类型成员?这有几个原因:
首先,我们不应该构建一个需要构造函数的结构.
public struct MyStruct
{
public Person p;
// public Person p = new Person(); // error: cannot have instance field initializers in structs
MyStruct(Person p)
{
p = new Person();
}
}
Run Code Online (Sandbox Code Playgroud)
其次,由于值类型语义:
MyStruct someVariable;
someVariable.p.Age = 2; // NullReferenceException
Run Code Online (Sandbox Code Playgroud)
编译器不允许我Person在声明中初始化.我必须把它移到构造函数,依赖调用者,或期望一个NullReferenceException.这些情况都不是理想的.
.NET Framework是否在值类型中有任何引用类型的示例?我们什么时候应该这样做(如果有的话)?
Mar*_*ell 20
值类型的实例永远不会包含引用类型的实例.引用类型对象位于托管堆上的某个位置,值类型对象可以包含对该对象的引用.这样的参考具有固定的大小.这样做很常见 - 例如每次在结构中使用字符串时.
但是,是的,您无法保证a中引用类型字段的初始化,struct因为您无法定义无参数构造函数(如果您使用C#以外的语言定义它,也无法保证它会被调用).
你说你应该"不构建一个struct需要构造函数".我说不然.由于值类型几乎总是不可变的,因此必须使用构造函数(很可能通过工厂到私有构造函数).否则它将永远不会有任何有趣的内容.
使用构造函数.构造函数很好.
如果您不想传入Person初始化的实例p,则可以通过属性使用延迟初始化.(因为显然公共场地p只是为了示范,对吧?对吗?)
public struct MyStruct
{
public MyStruct(Person p)
{
this.p = p;
}
private Person p;
public Person Person
{
get
{
if (p == null)
{
p = new Person(…); // see comment below about struct immutability
}
return p;
}
}
// ^ in most other cases, this would be a typical use case for Lazy<T>;
// but due to structs' default constructor, we *always* need the null check.
}
Run Code Online (Sandbox Code Playgroud)