簡體   English   中英

如何在基類中使用派生類屬性? C#

[英]How to use a derived class attribute in the base class? C#

我有這兩個類:

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錯誤。 我是否以錯誤的方式覆蓋字段屬性?

User類中使用構造函數並從BaseModel訪問屬性:

public class User : BaseModel
{
    public User()
    {
        fields = new List<String> {
            "id",
            "email",
            "name",
            "password"
        };
    }
}
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也可以在這里工作。

您應該在 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;
    }
}

這是否有幫助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();
        }
    }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM