Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/309.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# 在访问类属性时执行的方法(获取或设置)?_C#_Generics_Reflection_.net 3.5_Delegates - Fatal编程技术网

C# 在访问类属性时执行的方法(获取或设置)?

C# 在访问类属性时执行的方法(获取或设置)?,c#,generics,reflection,.net-3.5,delegates,C#,Generics,Reflection,.net 3.5,Delegates,C#-.net 3.5 我有一系列从同一基类继承的类。 我希望在访问派生类中的属性(get或set)时随时调用基类中的方法。但是,我不想在每个属性中编写代码来调用基类。。。相反,我希望有一种声明性的方式将此活动“下沉”到基类中 为需求添加一些香料,我确实需要确定被访问的属性的名称、属性值及其类型 我认为解决方案应该是委托、泛型和反射的巧妙组合。我可以设想在运行时创建某种类型的委托分配数组,但是在构造函数中迭代MemberInfo会对性能产生比我想象的更大的影响。同样,我希望有一种更直接的“声明式

C#-.net 3.5

我有一系列从同一基类继承的类。 我希望在访问派生类中的属性(get或set)时随时调用基类中的方法。但是,我不想在每个属性中编写代码来调用基类。。。相反,我希望有一种声明性的方式将此活动“下沉”到基类中

为需求添加一些香料,我确实需要确定被访问的属性的名称、属性值及其类型

我认为解决方案应该是委托、泛型和反射的巧妙组合。我可以设想在运行时创建某种类型的委托分配数组,但是在构造函数中迭代MemberInfo会对性能产生比我想象的更大的影响。同样,我希望有一种更直接的“声明式”方法来实现这一点


任何想法都非常感谢

我认为这不可能以声明的方式实现,我从未见过这样做。不过,您可以在基类上实现INotifyPropertyChanged接口,并在基类中实现该接口。大概是这样的:

public class A : INotifyPropertyChanged
{

    #region INotifyPropertyChanged Members

    public event PropertyChangedEventHandler PropertyChanged;

    #endregion

    protected virtual void RaiseOnPropertyChanged(object sender, string propertyName)
    {
        if (this.PropertyChanged != null)
            PropertyChanged(sender, new PropertyChangedEventArgs(propertyName);
    }

    public A()
    {
        this.PropertyChanged += new PropertyChangedEventHandler(A_PropertyChanged);
    }

    void A_PropertyChanged(object sender, PropertyChangedEventArgs e)
    {
        //centralised code here that deals with the changed property
    }
}


public class B : A
{
    public string MyProperty
    {
        get { return _myProperty; }
        set 
        {
            _myProperty = value;
            RaiseOnPropertyChanged(this, "MyProperty");
        }
    }

    public string _myProperty = null;
}

你不能自动完成,但你几乎可以免费得到95%。这是面向方面编程的经典案例。去看看,哪个有课。以下是解决问题的方法:

[Serializable]
public class FieldLogger : OnFieldAccessAspect {
    public override void OnGetValue(FieldAccessEventArgs eventArgs) {
        Console.WriteLine(eventArgs.InstanceTag);
        Console.WriteLine("got value!");
        base.OnGetValue(eventArgs);
    }

    public override void OnSetValue(FieldAccessEventArgs eventArgs) {
        int i = (int?)eventArgs.InstanceTag ?? 0;
        eventArgs.InstanceTag = i + 1;
        Console.WriteLine("value set!");
        base.OnSetValue(eventArgs);
    }

    public override InstanceTagRequest GetInstanceTagRequest() {
        return new InstanceTagRequest("logger", new Guid("4f8a4963-82bf-4d32-8775-42cc3cd119bd"), false);
    }
}

现在,从FieldLogger继承的任何内容都将获得相同的行为。普雷斯托

我还应该指出,虽然INotifyPropertyChanged允许您传递属性名称,但不需要火箭科学家更进一步地理解这个概念,并编写自己的接口版本,该接口还允许传递属性值等。虽然你所提出的,虽然在理论上听起来很聪明,但是会给你的应用程序增加很多开销,你必须考虑在你的代码中有条件编译开关。