在返回之前测试属性是否为空

我有以下财产

public MyType MyProperty {get;set;} 

我想更改此属性,以便如果值为null,它将首先填充该值,然后返回它…但使用私有成员变量。

例如,如果我这样做:

 public MyType MyProperty { get { if (_myProperty != null) return _myProperty else _myProperty = XYZ; return _myProperty; } set { _myProperty = value; } } 

这可能吗? 或者我需要成员变量才能完成它?

您需要一个成员变量和一个完整的属性声明。 自动实现的属性在它们是字段周围的无关包装时才适用,不涉及逻辑。 你可以稍微简化你的getter代码,顺便说一下:

 get { if (_myProperty == null) { _myProperty = XYZ; } return _myProperty; } 

(注意,如果没有额外的锁定,这些都不是线程安全的,但我认为没关系。)

顺便说一句,如果你使用自动实现的属性,你已经有了一个私有成员变量 – 只是编译器为你生成它。

 return _myProperty?? (_myProperty = XYZ); 

你能做的最好的事情就是在构造函数中给它一个值。 我知道这样你就失去了“延迟加载”,但你不能同时拥有自动属性和延迟加载。

你的代码:

 public MyType MyProperty {get;set;} 

请参阅“ 自动属性 ”,这只是“语法糖”,你可以在这里查看 。

编译器为属性生成字段,并在get集中生成指向该字段的代码。

 internal class ClassName { // Fields [CompilerGenerated] private MyType k__BackingField; // Properties public MyType MyProperty { [CompilerGenerated] get { return this.k__BackingField; } [CompilerGenerated] set { this.k__BackingField = value; } } } 

因此,您的代码将始终由编译器生成的字段支持。

你将需要一个私有变量来实现它,因为你的getter / setter中有逻辑。

如果您希望对获取或设置属性的行为进行任何修饰,那么您将丢失编译器生成的存储位​​置,因此您必须自己将值存储在某处。 私有成员变量在大多数情况下最有意义。

我建议考虑使用Lazy初始化 。 它不会帮助你避免成员变量,对此抱歉,但该代码将帮助您避免成员变量的内存预留,直到您的类需要该变量:

 public class MyType { public MyType() { XYZ(); } public void XYZ() { //some kind of initialization } } public class TestType { private Lazy _myProperty; public MyType MyProperty { get { return _myProperty.Value; }//_myProperty will be null until some code will try to read it } } 

要指出或实际提醒的另一件事是,你将无法绝对没有成员变量。 因为窗帘后面.Net编译器会创建该成员变量而不是你。 它只是不会通知您这一步骤。 但正如其他人所提到的那样,如果查看生成的MSIL,您将看到为您创建的成员变量。

您需要使用成员变量来完成它:

 public class MyClass { MyType _myProperty = null; public MyType MyProperty { get { if(_myProperty == null) _myProperty = XYZ; return _myProperty; } } } 

通过“成员变量”我假设你的意思是在属性get中定义的变量。 是的,您当然不需要本地定义的变量。 保存代码行代码的更常见模式是:

  if (_myProperty == null) _myProperty = XYZ; return _myProperty; 

如果通过“成员变量”表示支持字段,那么是的,您确实需要一个。 只有完全简单的“传递”字段/属性关系才能实现,而无需显式创建支持字段。 (即便如此,它也是由编译器创建的。)要实例化-if-null,您需要显式定义它。

是的,这是可能的。 但是你必须自己实现它,而不是自动属性。 您的属性不一定只需要使用成员变量,尽管这是默认值。

请记住,属性实际上已转换为Getter和Setter方法,您可以在其范围内执行大量工作。 虽然这种做法通常是气馁的。 良好实践表明,属性访问应该是快速的,并且不会长时间阻止客户端代码。

你可以这样做:

 public MyType MyProperty { get { if (_myProperty != null) return _myProperty else return XYZ; } set { _myProperty = value; } } 

仅当您使用成员变量时。

通常,我将延迟加载与IDisposable的实现结合起来,以便可以在Dispose方法中处理任何需要清理的变量。

如果需要该属性,那么一些检查可以使其防弹。 我倾向于使用类似的东西:

 public MyType MyProperty { get { if (_myProperty == null) _myProperty == XYZ; return _myProperty; } set { if(value == null) throw InvalidArgumentException(); _myProperty = value; } } 

使TDD更简单。

试试这个

 Public Class MyClass { Public MyType Alfa { If(this._Alfa == null) this.SetAlfa(); return _Alfa; } private MyType _Alfa {get;set;} private void SetAlfa() { //Somenthing to valorize _Alfa } }