我们假设我有一个名为Customer
的类,其中包含一些属性:
public class Customer
{
public string CustAddr = GetCustAddr(); //Long procedure returning address
public double CustAcct = GetCustAcct(); //Long procedure returning account
public string CustInvoice = GetCustInvoice(); //Long procedure returning invoice
}
该类通过函数返回:
public Customer GetData(string query)
{
Customer cust = new Customer();
//set the values for each of the properties
return cust;
}
现在它正在返回全班,我可以像这样使用它:
lblDisplay = GetData("QUERY").CustAddr.ToString();
但是,假设每个属性都需要花费大量时间来计算。如果我只想要CustAddr值,它仍会计算并且CustAcct
和CustInvoice
可供我使用。
如何将我的功能改为仅返回我正在寻找的属性,除了将我的班级分成单独的程序来调用?例如,我可以:
lblDisplay = GetCustAddr().ToString();
但这不是我想要的。我认为将所有数据放在有组织的结构而不是一堆不同的程序中会更好。
答案 0 :(得分:5)
这是延迟初始化的理想选择。这里我给出一个使用属性的例子(你有字段)。
public class Customer
{
public Lazy<string> CustAddr { get; private set; }
public Lazy<double> CustAcct { get; private set; }
public Lazy<string> CustInvoice { get; private set; }
public Customer()
{
CustAddr = new Lazy<string>(GetCustAddr);
CustAcct = new Lazy<double>(GetCustAcct);
CustInvoice = new Lazy<string>(GetCustInvoice);
}
}
但是,如果我没有指出你不应该使用浮点类型(float
,double
)来存储货币价值,那将是我的疏忽。请考虑使用decimal
。
答案 1 :(得分:2)
为什么在有香草味的情况下使用异国情调的解决方案?
在属性的get
上实施计算。
注意:你拥有的是公共领域,而不是属性
非常简单的解决方案(没有异国情调!)
请参阅this fiddle
e.g。
public class Customer
{
private double ? _custAcct = null;
public double CustAcct
{
get
{
if (!_custAcct.HasValue)
{
_custAcct = GetCustAcct();
}
return _custAcct.Value;
}
}
private double GetCustAcct()
{
// do something that takes a long time
return 1234.45;
}
}
答案 2 :(得分:1)
您所说的是延迟加载或延迟初始化。你写的属性是这样的:
public class MyLazyWidget
{
. . .
public BigExpensiveObject MyLazyProperty
{
get
{
if ( BigExpensiveObjectBackingStore == null )
{
BigExpensiveObjectBackingStore = ExpensiveOperation() ;
}
return BigExpensiveObjectBackingStore ;
}
}
private static BigExpensiveObjectBackingStore = null ;
. . .
}
如果你的应用是多线程的,你需要担心竞争条件,所以你需要同步访问静态后备存储:
public class MyLazyWidget
{
. . .
public BigExpensiveObject MyLazyProperty
{
get
{
lock( MyLazyPropertyLatch )
{
if ( BigExpensiveObjectBackingStore == null )
{
BigExpensiveObjectBackingStore = ExpensiveOperation() ;
}
}
return BigExpensiveObjectBackingStore ;
}
}
private static readonly object MyLazyPropertyLatch = new object() ;
private static BigExpensiveObjectBackingStore = null ;
. . .
}