如何在基类中使用派生类属性? C#

时间:2019-12-27 16:41:50

标签: c# .net asp.net-mvc

我有这两节课:

abstract class BaseModel
{
  ...
  public List<String> fields;
  ...
  public DataSet select(){
    //ex : this here the fields is null; but this class being abstract means
    // I can only call this from an inherited class of this (child class)
    // which will have the fields attributes override
    this.fields.Count();
  }
}

public class User : BaseModel
{
  public new List<String> fields = new List<String> {
    "id",
    "email",
    "name",
    "password"
  };
}

如果创建新的User实例,然后调用select方法,则会收到null错误。 我会以错误的方式覆盖字段属性吗?

4 个答案:

答案 0 :(得分:3)

User类中使用构造函数,并从BaseModel访问属性:

public class User : BaseModel
{
    public User()
    {
        fields = new List<String> {
            "id",
            "email",
            "name",
            "password"
        };
    }
}

答案 1 :(得分:2)

public class User : BaseModel
{
  public new List<String> fields = ...
}

您正在使用new,它与您想要的相反。 new声明此字段与任何基类中任何类似命名的字段无关

您可以在此处使用几种方法。为了我个人的喜好:

不要重新声明该字段,而是使用构造函数:

public abstract class BaseModel
{
    public List<String> fields = new List<string>();
}

public class User : BaseModel
{
    public User()
    {
        fields.AddRange(new List<String> {
            "id",
            "email",
            "name",
            "password"
        });
    }
}

您还可以使用基本构造函数。此处可能没有必要,但有时更清洁。很好的是,您的基类可以强制将派生类传递到字段列表中,以防止开发人员忘记和引入错误。

public abstract class BaseModel
{
    public List<String> fields;

    public BaseModel(List<String> fieldsList)
    {
        this.fields = fieldsList;
    }
}

public class User : BaseModel
{
    public User() : base(new List<String> { "id", "email", "name", "password" })
    {

    }
}

将基本属性(不是字段!)设置为virtual(或abstract)并在派生类中覆盖它:

public abstract class BaseModel
{
    public virtual List<String> fields { get; set; } = new List<string>();
}

public class User : BaseModel
{
    public override List<String> fields { get; set; } = new List<String> { "id", "email", "name", "password" };
}

abstract也可以在这里工作。

您还可以在此处使用方法而不是属性。并不是说不能覆盖属性,而是更常用方法来实现:

public abstract class BaseModel
{
    public virtual List<String> GetFields()
    {
        return new List<String>();
    }
}

public class User : BaseModel
{
    public override List<String> GetFields()
    {
        return new List<String> {
            "id",
            "email",
            "name",
            "password"
        };
    }
}

abstract也可以在这里工作。

答案 2 :(得分:1)

您应该在BaseModel中声明一个抽象方法GetFields,并在所有子类中覆盖它:

public abstract class BaseModel
{
    public abstract List<String> GetFields();
}

public class User : BaseModel
{
    private static readonly List<String> FIELDS = 
            new List<String>{"id", "email", "name", "password"};

    public override List<String> GetFields()
    {
        return FIELDS;
    }
}

答案 3 :(得分:0)

此帮助https://dotnetfiddle.net/1crFh2

    public abstract class BaseModel
    {
        public List<String> fields = new List<string>();

        public int select()
        {
            //ex : this here the fields is null; but this class being abstract means
            // I can only call this from an inherited class of this (child class)
            // which will have the fields attributes override
            return this.fields.Count();
        }
    }

    public class User : BaseModel
    {

        public User()
        {
            var theFields = new List<String> {
                "id",
                "email",
                "name",
                "password"
            };
            fields.AddRange(theFields);
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            var user = new User();
            var q = user.select();
        }
    }
相关问题