繁体   English   中英

C#在继承的类中为父级属性添加自定义属性

[英]C# add custom attributes for a parent's property in an inherited class

我在通用DataGrid中显示Business Object,并且想通过自定义属性设置列标题,例如:

class TestBo
 {
    [Header("NoDisp")]
    public int ID {get; set;}

    [Header("Object's name")]
    public String Name { get; set; }
}

到目前为止,一切都很好,但是我还想通过继承将显示内容与数据分开:

class TestBO
{
   public int ID {get; set;}
   public String Name { get; set; }
}

class TestPresentationBO : TestBO
{
  //Question: how to simply set the Header attribute on the different properties?
}

我在Child构造函数中使用SetCustomAttribute通过反射看到了一个解决方案,但这将很麻烦,所以有没有简单而优雅的方法来解决此问题?

请防止我破坏数据/表示的分隔; o)

问题:如何简单地在不同属性上设置Header属性?

由于属性是特定于类型的,因此无法按照建议的方式在继承的成员上设置属性。 SetCustomAttribute不会帮助您-只有在运行时构造新类型时,它才有好处。 编译属性后,您将无法在运行时对其进行更改,因为它是元数据的一部分。

如果要保持分离,则必须寻找另一种方法。

(您可以将属性设置为虚拟属性,在Presentation类中覆盖它们,并在覆盖上添加属性,但这看起来很狡猾,并且没有真正分开任何内容-无论如何,您最终在TestPresentationBO中得到了一个完整的TestBO类...)

将属性在TestBo虚拟化,并在TestPresentationBO覆盖它们。 这样,您可以添加属性。

您可以像WCF RIA服务一样进行操作。 将属性添加到TestBO,例如[Presentation]以类型作为参数。 此新类型将重新定义属性,但具有表示属性。 在运行时,您必须获取新类型的标识并获取其属性的自定义属性。

或者忘记属性,并拥有一个将BO与表示BO类映射的字典。 此演示BO类的功能与上述相同,即使用自定义属性重新定义属性。

演示文稿BO类从不实例化,只需将其反射即可获得演示文稿信息。

只是在想,您不能使用部分类和MetadatatypeAttribute解决此问题吗? MVC2使用此模式进行模型验证。

您是否正在使用MVVM(模型视图视图模型)模式? 在我看来,部分地从其他答案来看,您无法真正使用所需的自定义属性来执行此操作。 但是,它也似乎我说你TestPresentationBO真的就像一个“视图模式” TestBO 视图模型基本上是业务或逻辑类的包装或代理,这基本上就是您想要的。 (视图模型的摘要可能不是100%准确;我只是从MVVM开始。)

您可以创建一个TestBOViewModel来包装TestBO ,然后将TestBO的集合TestBOViewModel给datagrid。 当然,您可以用[Header("Object's name")]等装饰暴露包装的类的属性。这不使用继承,但是我不明白为什么在这种情况下需要使用继承。 但是,使用视图模型确实通过使用包装器(视图模型)将演示文稿(视图)与数据(模型)清晰地分开。

有关MVVM模式的更多信息,我发现这很有趣: 具有Model-View-ViewModel设计模式的WPF应用程序

这样的事情。 当然,您也可以在此处添加验证和其他功能。

public class TestBOViewModel // extend from DependencyObject 
{                            // if you want to use dependency properties

    private TestBO _myBO;

    public TestBOViewModel(TestBO bo)
    {
        _myBO = bo;
    }

    [Header("NoDisp")]
    public int ID 
    {
        get { return _myBO.ID; }
        set { _myBO.ID = value; }
    }
}

对于C#6.0,您可以轻松隐藏继承的成员并引入自己的属性。 但是,这可能会隐藏原始属性上的所有属性。 同样,这种简化的语法使属性变为只读,因此您可能需要自己通过管道传递获取/设置。

public class User
{
    public string Login { get; set; }
}


public class UserDetail : User
{
    [Display(Name = "Login:")]
    public new string Login => base.Login;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM