Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/320.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
有没有办法在C#中截取setter和getter?_C#_Interceptor_Getter Setter - Fatal编程技术网

有没有办法在C#中截取setter和getter?

有没有办法在C#中截取setter和getter?,c#,interceptor,getter-setter,C#,Interceptor,Getter Setter,在Ruby和PHP(我猜还有其他语言)中,每当设置属性时都会调用一些实用方法。(*Ruby的实例变量集*,PHP的实例变量集*) 那么,假设我有一个C#类,如下所示: public class Person { public string FirstName { get; set; } public string LastName { get; set; } } 现在,假设调用了Person类中的任何属性setter,我想先调用另一个方法,然后继续使用setter的默认行为,这

在Ruby和PHP(我猜还有其他语言)中,每当设置属性时都会调用一些实用方法。(*Ruby的实例变量集*,PHP的实例变量集*)

那么,假设我有一个C#类,如下所示:

public class Person
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
}
现在,假设调用了
Person
类中的任何属性setter,我想先调用另一个方法,然后继续使用setter的默认行为,这同样适用于属性setter

这可能吗


编辑:
我希望在不定义支持字段的情况下执行此操作。

您必须完整地写入属性才能实现此目的。

不是现成的。您需要手动或使用IL重写自动地将代码插入每个属性setter和getter

如果要手动执行,则不能再使用自动属性。

如果要自动执行此操作,请查看AOP。

可以直接在属性体本身中执行此操作,但是需要使用适当的支持字段,而不是

即使使用自动实现的属性,您也会得到一个支持字段——它是由编译器生成的,您没有直接访问它的权限


编辑:


鉴于您不需要支持字段,您还有其他选择—使用诸如PostSharp之类的AOP工具可能会有所帮助。

通常不需要;尽管有一些选择

  • 继承自-允许这样做,但要以性能为代价
  • 编写一个显式属性(即带有支持字段),并手动添加一个实用程序方法调用
  • 查看编译时编织器,例如-通常通过发现属性或类似属性
  • 看看一些DI/IoC工具(以及其他一些基于“decorator”的工具)提供的运行时代码生成器,它们要么修饰对象,要么对对象进行子类化,以添加额外的代码
  • 是的,当然

    在您的示例中,您使用的是自动属性,没有支持字段。。。。您只需要为属性创建一个支持字段,然后就可以在setter和getter中执行您想要的操作

    例如:

    private string firstName;
    
    public string FirstName
    {
     get { return firstName; }
    
     set { doMethod(); firstName = value;}
    }
    

    据我所知,您必须使用一个backing字段并将对另一个方法的调用放入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; }
        }
    }
    

    模拟框架可以做到这一点,就像IoC库一样。唯一的其他方法是使用IL重写(如前所述)。

    您不能使用自动属性。您必须使用一个支持字段以旧的方式对属性进行dinfe,并手动调用该方法

    public class Person
    {
        private string _FirstName;
        public string FirstName 
        { 
            get
            {
                return _FirstName;
            }
            set
            {
                SomeMethod();
                _FirstName = value;
            }
        }
        private void SomeMethod()
        {
            //do something
        }
    
    }
    

    我知道这已经得到了正确的回答,但我将提供一个示例,向您展示实现所需功能的语法:

    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);
            }
        }
    }
    

    您是否能够重写类以实现接口?如果是这样的话,你可能会得到你所需要的。如果接口不是一个选项,那么该链接也会记录Unity的类型和实例拦截器。

    您能否提供一个链接,说明如何通过
    ContextBoundObject
    执行此操作?谢谢。我认为在这种情况下也可以使用
    DynamicObject
    (覆盖
    TrySetMember
    )。但是
    ContextBoundObject
    ?@Danny-归根结底,属性是方法-所以类似的东西应该可以工作:你现在展示的方法在MSIL中实现了一个支持字段,那么你为什么不想要一个呢?@Mr47当然,但我不想自己定义它。我想要一个自动的方法来做这件事。我担心任何其他的方法都会比仅仅有一个支持字段更麻烦。
    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);
            }
        }
    }