我有以下属性
public MyType MyProperty {get;set;}
我想更改此属性,以便如果该值为null,它将首先填充该值,然后将其返回...但不使用使用私有成员变量。
例如,如果我这样做:
public MyType MyProperty
{
get
{
if (_myProperty != null)
return _myProperty
else
_myProperty = XYZ;
return _myProperty;
}
set
{
_myProperty = value;
}
}
这可能吗?或者我是否需要成员变量来完成它?
答案 0 :(得分:33)
您需要一个成员变量和一个完整的属性声明。自动实现的属性仅适用,如果它们是字段周围的琐碎包装器,不涉及逻辑。你可以稍微简化你的getter代码,顺便说一下:
get
{
if (_myProperty == null)
{
_myProperty = XYZ;
}
return _myProperty;
}
(请注意,如果没有额外的锁定,这些都不是线程安全的,但我认为没关系。)
顺便说一句,如果您使用自动实现的属性,那么您已经拥有私有成员变量 - 这只是编译器为您生成它。
答案 1 :(得分:12)
return _myProperty?? (_myProperty = XYZ);
答案 2 :(得分:10)
你能做的最好的事情就是在构造函数中给它一个值。我知道这样你就失去了“延迟加载”,但你不能同时拥有自动属性和延迟加载。
答案 3 :(得分:4)
您的代码:
public MyType MyProperty {get;set;}
请参阅“Automatic Properties”,这只是“语法糖”,因为您可以查看here。
编译器为其生成字段 该属性,也生成了 get set中的代码指向 字段。
internal class ClassName { // Fields [CompilerGenerated] private MyType <Property>k__BackingField; // Properties public MyType MyProperty { [CompilerGenerated] get { return this.<Property>k__BackingField; } [CompilerGenerated] set { this.<Property>k__BackingField = value; } } }
因此,您的代码将始终由编译器生成的字段支持。
答案 4 :(得分:2)
您需要使用成员变量来完成它:
public class MyClass
{
MyType _myProperty = null;
public MyType MyProperty
{
get
{
if(_myProperty == null)
_myProperty = XYZ;
return _myProperty;
}
}
}
答案 5 :(得分:1)
你需要一个私有变量来实现它,因为你的getter / setter中有逻辑。
答案 6 :(得分:1)
如果您希望对获取或设置属性的行为进行任何修饰,那么您将丢失编译器生成的存储位置,因此您必须自己将值存储在某处。在大多数情况下,私有成员变量最有意义。
答案 7 :(得分:1)
我建议考虑使用Lazy initialization。 它不会帮助你避免成员变量,对此抱歉,但该代码将帮助你避免成员变量的内存预留,直到你的类需要该变量:
public class MyType
{
public MyType()
{
XYZ();
}
public void XYZ()
{
//some kind of initialization
}
}
public class TestType
{
private Lazy<MyType> _myProperty;
public MyType MyProperty
{
get { return _myProperty.Value; }//_myProperty will be null until some code will try to read it
}
}
要指出或实际提醒的另一件事是,你将无法绝对没有成员变量。因为幕后.Net编译器将创建该成员变量而不是你。它只是不会通知您这一步骤。但正如其他人所提到的,如果你查看生成的MSIL,你会看到为你创建的成员变量。
答案 8 :(得分:0)
是的,这是可能的。但是你必须自己实现它,而不是自动属性。您的属性不一定只需要使用成员变量,尽管这是默认值。
请记住,属性实际上已转换为Getter和Setter方法,您可以在其范围内完成大量工作。虽然这种做法通常是气馁的。良好实践表明,属性访问应该是快速的,并且不会长时间阻止客户端代码。
你可以这样做:
public MyType MyProperty
{
get
{
if (_myProperty != null)
return _myProperty
else
return XYZ;
}
set
{
_myProperty = value;
}
}
答案 9 :(得分:0)
仅当您使用成员变量时。
通常,我将延迟加载与implementation of IDisposable结合使用,以便可以在Dispose方法中处理任何需要清理的变量。
答案 10 :(得分:0)
通过“成员变量”我假设你的意思是在属性get中定义的变量。是的,您当然不需要本地定义的变量。保存代码行代码的更常见模式是:
if (_myProperty == null)
_myProperty = XYZ;
return _myProperty;
如果通过“成员变量”表示支持字段,那么是的,您确实需要一个。只有完全简单的“传递”字段/属性关系才能实现,而无需显式创建支持字段。 (即便如此,它也是由编译器创建的。)要实例化-if-null,您需要明确定义它。
答案 11 :(得分:0)
如果该属性是必需的,那么一些检查可以使其成为防弹。我倾向于使用类似的东西:
public MyType MyProperty
{
get
{
if (_myProperty == null)
_myProperty == XYZ;
return _myProperty;
}
set
{
if(value == null)
throw InvalidArgumentException();
_myProperty = value;
}
}
使TDD更简单。
答案 12 :(得分:0)
试试这个
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
}
}