在Ruby和PHP(我猜其他语言)中,只要设置了属性,就会调用一些实用程序方法。 (Ruby的 * instance_variable_set * ,PHP的 * __ set * )。
所以,假设我有一个像这样的C#类:
public class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
}
现在,假设如果调用Person
类中的任何属性设置器,我想先调用另一个方法,然后继续使用setter的默认行为,这同样适用于属性setter
这可能吗?
修改 的 我想在没有定义支持字段的情况下这样做。
答案 0 :(得分:28)
一般情况下;但有几个选择;
答案 1 :(得分:14)
可以直接在属性体中进行,但是您需要使用适当的支持字段而不是auto-implemented properties。
private string firstName;
public string FirstName
{
get { return firstName;}
set
{
if(check(value))
{
firstName = value;
}
}
}
即使使用自动实现的属性,您也会获得一个支持字段 - 这是由编译器生成的,您无法直接访问它。
编辑:
看到你不想要一个支持领域,你还有其他的选择 - 使用像PostSharp这样的AOP工具可以帮助你。
答案 2 :(得分:4)
您必须完整地编写属性才能实现此目的。
答案 3 :(得分:2)
我知道这已经得到了适当的回答,但我会举一个例子向您展示实现您想要的语法:
public class Person
{
private
public string FirstName
{
get
{
return _firstName;
}
set
{
// see how we can call a method below? or any code for that matter..
_firstName = SanitizeName(value);
}
}
}
答案 4 :(得分:2)
您是否可以重写您的类来实现接口?如果是这样,Unity's interface interceptor可能会为您提供所需内容。如果接口不是一个选项,那么该链接也会记录Unity的类型和实例拦截器。
答案 5 :(得分:1)
没有开箱即用。您需要手动或自动使用IL重写将代码插入每个属性setter和getter。
如果您想手动执行此操作,则无法再使用自动属性 如果您想自动执行此操作,请查看AOP。
答案 6 :(得分:1)
是的,当然......
在您的示例中,您使用的是自动属性,没有支持字段....您只需要为您的属性创建一个支持字段,然后您就可以在setter和getter中执行您想要的操作。
示例:
private string firstName;
public string FirstName
{
get { return firstName; }
set { doMethod(); firstName = value;}
}
答案 7 :(得分:1)
模拟框架可以做到这一点,以及像Unity这样的IoC库。执行此类操作的唯一方法是使用IL重写(如前所述)。
答案 8 :(得分:1)
您无法使用自动属性。您必须使用支持字段以旧方式定义属性并手动调用该方法。
public class Person
{
private string _FirstName;
public string FirstName
{
get
{
return _FirstName;
}
set
{
SomeMethod();
_FirstName = value;
}
}
private void SomeMethod()
{
//do something
}
}
答案 9 :(得分:0)
据我所知,你必须使用一个支持字段,然后将调用放入setter中的另一个方法:
public class Person {
private string firstName;
private string lastName;
public string FirstName {
set {
DoSomeStuff();
firstName = value;
}
get { return firstName; }
}
public string LastName {
set {
DoSomeStuff();
lastName = value;
}
get { return lastName; }
}
}
答案 10 :(得分:0)
是的,您可以使用装饰器设计模式。