从基类中的派生类获取属性

Mar*_* M. 6 c# oop reflection

如何从基类中的派生类获取属性?

基类:

public abstract class BaseModel {
    protected static readonly Dictionary<string, Func<BaseModel, object>>
            _propertyGetters = typeof(BaseModel).GetProperties().Where(p => _getValidations(p).Length != 0).ToDictionary(p => p.Name, p => _getValueGetter(p));
}
Run Code Online (Sandbox Code Playgroud)

派生类:

public class ServerItem : BaseModel, IDataErrorInfo {
    [Required(ErrorMessage = "Field name is required.")]
    public string Name { get; set; }
}

public class OtherServerItem : BaseModel, IDataErrorInfo {
    [Required(ErrorMessage = "Field name is required.")]
    public string OtherName { get; set; }

    [Required(ErrorMessage = "Field SomethingThatIsOnlyHereis required.")]
    public string SomethingThatIsOnlyHere{ get; set; }
}
Run Code Online (Sandbox Code Playgroud)

在这个例子中 - 我可以在BaseModel类中从ServerItem类获取"Name"属性吗?

编辑:我正在尝试实现模型验证,如下所述:http: //weblogs.asp.net/marianor/archive/2009/04/17/wpf-validation-with-attributes-and-idataerrorinfo-interface-in -mvvm.aspx

我想如果我用(几乎)所有的验证魔法创建一些基础模型,然后扩展该模型,它就可以了...

Mat*_*son 7

如果要求派生类必须实现方法或属性,则应将该方法或属性作为抽象声明引入基类.

例如,对于您的Name属性,您将添加到基类:

public abstract string Name { get; set; }
Run Code Online (Sandbox Code Playgroud)

然后,任何派生类都必须实现它,或者是抽象类本身.

一旦将Name属性的抽象版本添加到基类,除了基类的构造函数之外,您将能够在基类中访问它.

  • 是的,但是我不想将派生模型中的每个属性都放到基类中-毫无意义:) (2认同)

rr-*_*rr- 6

如果必须从基类中确实获取派生类的属性,则可以使用Reflection,例如,像这样...

using System;
public class BaseModel
{
    public string getName()
    {
        return (string) this.GetType().GetProperty("Name").GetValue(this, null);
    }
}

public class SubModel : BaseModel
{
    public string Name { get; set; }
}

namespace Test
{
    class Program
    {
        static void Main(string[] args)
        {
            SubModel b = new SubModel();
            b.Name = "hello";
            System.Console.Out.WriteLine(b.getName()); //prints hello
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

但是不建议这样做,您很可能应该像Matthew所说的那样重新考虑您的设计。

至于不将属性扔给基类-您可以尝试将基类和派生类分离为不相关的对象,并通过构造函数传递它们。


pas*_*ein 5

如果两个类都在同一个程序集中,您可以尝试这样做:

Assembly
    .GetAssembly(typeof(BaseClass))
    .GetTypes()
    .Where(t => t.IsSubclassOf(typeof(BaseClass))
    .SelectMany(t => t.GetProperties());
Run Code Online (Sandbox Code Playgroud)

这将为您提供所有子类的所有属性BaseClass.