为多个 getter 执行的公共操作
Common action executed for multiple getters
我正在尝试找到一种巧妙的方法来在首次访问多个 getter 之一时触发加载机制。我的第一个想法是这样的:
public class Customer {
private bool loaded = false;
public int PK { get; set; }
public string Email { get; set; }
public string Name { get { if (!loaded) loadData(); return _name; } set { ... } }
public string Street { get { if (!loaded) loadData(); return _street; } set { ... } }
public string City { get { if (!loaded) loadData(); return _city; } set { ... } }
}
简而言之,在此示例中,每个 Customer
都存在其基础数据 PK
和 Email
,直到访问其他属性之一。
这意味着很多重复代码,随着 class 的复杂性而增加。有没有办法为这些属性创建某种继承?
类似这样,但我认为这不可能:
private void checkData() { if (!loaded) loadData(); }
public string Name:checkData { get; set; }
public string Street:checkData { get; set; }
public string City:checkData { get; set; }
另一种方法可能是通过反思,但由于我没有经验,我不知道从哪里开始。
非常感谢任何提示! ;-)
您可以使用 Lazy<T>
class 来包装次要属性。
这样 loadData
只会在调用任何辅助 getter 时执行,并且不会执行多次。
public class Customer
{
public int PK { get; set; }
public string Email { get; set; }
public string Name { get { return data.Value.Name; } }
public string Street { get { return data.Value.Street; } }
public string City { get { return data.Value.City; } }
public Customer()
{
data = new Lazy<CustomerData>(loadData);
}
private CustomerData loadData()
{
...
}
private struct CustomerData
{
public string Name, Street, City;
}
private Lazy<CustomerData> data;
}
还有另一种不太漂亮的方式。您可以编写一个包装通用方法,从而减少属性中的代码。
这是一个例子:
public string Name
{
get { return Get(m_name); }
set { m_name = value; }
}
public static T Get<T>(T value)
{
if (!loaded)
{
loadData();
}
return value;
}
请注意,这会降低性能,因为您的属性总是会调用额外的方法。您可以尝试强制编译器内联该方法(如果它尚未发生)。
我正在尝试找到一种巧妙的方法来在首次访问多个 getter 之一时触发加载机制。我的第一个想法是这样的:
public class Customer {
private bool loaded = false;
public int PK { get; set; }
public string Email { get; set; }
public string Name { get { if (!loaded) loadData(); return _name; } set { ... } }
public string Street { get { if (!loaded) loadData(); return _street; } set { ... } }
public string City { get { if (!loaded) loadData(); return _city; } set { ... } }
}
简而言之,在此示例中,每个 Customer
都存在其基础数据 PK
和 Email
,直到访问其他属性之一。
这意味着很多重复代码,随着 class 的复杂性而增加。有没有办法为这些属性创建某种继承?
类似这样,但我认为这不可能:
private void checkData() { if (!loaded) loadData(); }
public string Name:checkData { get; set; }
public string Street:checkData { get; set; }
public string City:checkData { get; set; }
另一种方法可能是通过反思,但由于我没有经验,我不知道从哪里开始。
非常感谢任何提示! ;-)
您可以使用 Lazy<T>
class 来包装次要属性。
这样 loadData
只会在调用任何辅助 getter 时执行,并且不会执行多次。
public class Customer
{
public int PK { get; set; }
public string Email { get; set; }
public string Name { get { return data.Value.Name; } }
public string Street { get { return data.Value.Street; } }
public string City { get { return data.Value.City; } }
public Customer()
{
data = new Lazy<CustomerData>(loadData);
}
private CustomerData loadData()
{
...
}
private struct CustomerData
{
public string Name, Street, City;
}
private Lazy<CustomerData> data;
}
还有另一种不太漂亮的方式。您可以编写一个包装通用方法,从而减少属性中的代码。
这是一个例子:
public string Name
{
get { return Get(m_name); }
set { m_name = value; }
}
public static T Get<T>(T value)
{
if (!loaded)
{
loadData();
}
return value;
}
请注意,这会降低性能,因为您的属性总是会调用额外的方法。您可以尝试强制编译器内联该方法(如果它尚未发生)。