簡體   English   中英

標記為“虛擬”的類成員集合與不帶“虛擬”關鍵字的成員集合有什么區別

[英]What is the difference between class member collection marked as “virtual” and one without “virtual” keyword

鑒於以下。 有和沒有虛擬關鍵字有什么區別?

public class Test
{
    public Test()
    {
        this.UserTests = new List<UserTest>();
    }
    public int TestId { get; set; }
    public virtual ICollection<UserTest> UserTests { get; set; }
}

請考慮以下PersonEmployee類:

public class Person
{
    public string Name { get; set; }

    public string WhoAmI()
    {
        return "I'm just a person and my name is " + this.Name;
    }
}

public class Employee : Person
{
    public string WhoAmI()
    {
        return "I'm an employed person and my name is " + this.Name;
    }
}

如您所見, WhoAmI方法未在任何類中標記為virtualoverride 但是,當您運行以下代碼時:

Employee p = new Employee { Name = "John Smith" };
p.WhoAmI(); // yields "I'm an employed person and my name is John Smith"

但是,此代碼:

Person p = new Employee { Name = "John Smith" };
p.WhoAmI(); // yields "I'm just a person and my name is John Smith" 

差異的原因很簡單。 在第一種情況下,您通過將p變量稱為Employee來明確指示編譯器調用更具體的WhoAmI ,然后將調用Employee.WhoAmI

在后一種情況下,我們將p稱為其基類Person因此調用了Person.WhoAmI

多態性:

如果我們希望即使將p稱為Person我們仍然能夠調用更具體的實現該怎么辦?

在這種情況下, virtualoverride便會派上用場:

public class Person
{
    public string Name { get; set; }

    public virtual string WhoAmI()
    {
        return "I'm just a person and my name is " + this.Name;
    }
}

public class Employee : Person
{
    public override string WhoAmI()
    {
        return "I'm an employed person and my name is " + this.Name;
    }
}

現在,它會產生“正確”的結果:

Person p = new Employee { Name = "John Smith" };
p.WhoAmI(); // yields "I'm an employed person and my name is John Smith"

另外,使用多態列表時:

var data = new List<Person>();
data.Add(new Person { Name = "Regular Person" });
data.Add(new Employee { Name = "Employed Person" });

foreach (var p in data)
{
     p.WhoAmI(); // will call the 'correct' method
 }

這意味着,如果需要的話,可以從您的Testclass派生其他一些class ,那么它將能夠使用其他邏輯來覆蓋繼承的UserTests屬性邏輯,例如:

    private ICollection<UserTest> _userTests;
    public class ComplexTest : Test
    {
        public override ICollection<UserTest> UserTests
        {
          get { return _userTests.Where(...)} //class-specific logic 
          set { _userTests = value }
        }
    }

暫無
暫無

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

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