标记为“虚拟”的类成员集合与没有“虚拟”关键字的类成员集合之间有什么区别

时间:2014-03-30 14:42:13

标签: c# inheritance

鉴于以下内容。拥有和不拥有虚拟关键字有什么区别?

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

2 个答案:

答案 0 :(得分:2)

考虑以下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" 

差异的原因很简单。在第一种情况下,您明确指示编译器通过将WhoAmI变量引用为p来调用更具体的Employee,然后将调用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
 }

答案 1 :(得分:0)

这意味着如果其他class来自您的Test基地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 } } } 1}}属性逻辑与其他逻辑,例如:

{{1}}