In the following blog: http://weblogs.asp.net/scottgu/archive/2010/07/16/code-first-development-with-entity-framework-4.aspx
The blog contains the following code sample:
public class Dinner
{
public int DinnerID { get; set; }
public string Title { get; set; }
public DateTime EventDate { get; set; }
public string Address { get; set; }
public string HostedBy { get; set; }
public virtual ICollection<RSVP> RSVPs { get; set; }
}
public class RSVP
{
public int RsvpID { get; set; }
public int DinnerID { get; set; }
public string AttendeeEmail { get; set; }
public virtual Dinner Dinner { get; set; }
}
What is the purpose of using virtual
when defining a property in a class? What effect does it have?
This question is related to
c#
class
properties
virtual
The virtual keyword is used to modify a method, property, indexer, or event declaration and allow for it to be overridden in a derived class. For example, this method can be overridden by any class that inherits it:
public virtual double Area()
{
return x * y;
}
You cannot use the virtual modifier with the static, abstract, private, or override modifiers. The following example shows a virtual property:
class MyBaseClass
{
// virtual auto-implemented property. Overrides can only
// provide specialized behavior if they implement get and set accessors.
public virtual string Name { get; set; }
// ordinary virtual property with backing field
private int num;
public virtual int Number
{
get { return num; }
set { num = value; }
}
}
class MyDerivedClass : MyBaseClass
{
private string name;
// Override auto-implemented property with ordinary property
// to provide specialized accessor behavior.
public override string Name
{
get
{
return name;
}
set
{
if (value != String.Empty)
{
name = value;
}
else
{
name = "Unknown";
}
}
}
}
We can't talk about virtual members without referring to polymorphism. In fact, a function, property, indexer or event in a base class marked as virtual will allow override from a derived class.
By default, members of a class are non-virtual and cannot be marked as that if static, abstract, private, or override modifiers.
Example Let's consider the ToString() method in System.Object. Because this method is a member of System.Object it's inherited in all classes and will provide the ToString() methods to all of them.
namespace VirtualMembersArticle
{
public class Company
{
public string Name { get; set; }
}
class Program
{
static void Main(string[] args)
{
Company company = new Company() { Name = "Microsoft" };
Console.WriteLine($"{company.ToString()}");
Console.ReadLine();
}
}
}
The output of the previous code is:
VirtualMembersArticle.Company
Let's consider that we want to change the standard behavior of the ToString() methods inherited from System.Object in our Company class. To achieve this goal it's enough to use the override keyword to declare another implementation of that method.
public class Company
{
...
public override string ToString()
{
return $"Name: {this.Name}";
}
}
Now, when a virtual method is invoked, the run-time will check for an overriding member in its derived class and will call it if present. The output of our application will then be:
Name: Microsoft
In fact, if you check the System.Object class you will find that the method is marked as virtual.
namespace System
{
[NullableContextAttribute(2)]
public class Object
{
....
public virtual string? ToString();
....
}
}
In the context of EF, marking a property as virtual allows EF to use lazy loading to load it. For lazy loading to work EF has to create a proxy object that overrides your virtual properties with an implementation that loads the referenced entity when it is first accessed. If you don't mark the property as virtual then lazy loading won't work with it.
It’s quite common to define navigational properties in a model to be virtual. When a navigation property is defined as virtual, it can take advantage of certain Entity Framework functionality. The most common one is lazy loading.
Lazy loading is a nice feature of many ORMs because it allows you to dynamically access related data from a model. It will not unnecessarily fetch the related data until it is actually accessed, thus reducing the up-front querying of data from the database.
From book "ASP.NET MVC 5 with Bootstrap and Knockout.js"
I understand the OPs frustration, this usage of virtual is not for the templated abstraction that the defacto virtual modifier is effective for.
If any are still struggling with this, I would offer my view point, as I try to keep the solutions simple and the jargon to a minimum:
Entity Framework in a simple piece does utilize lazy loading, which is the equivalent of prepping something for future execution. That fits the 'virtual' modifier, but there is more to this.
In Entity Framework, using a virtual navigation property allows you to denote it as the equivalent of a nullable Foreign Key in SQL. You do not HAVE to eagerly join every keyed table when performing a query, but when you need the information -- it becomes demand-driven.
I also mentioned nullable because many navigation properties are not relevant at first. i.e. In a customer / Orders scenario, you do not have to wait until the moment an order is processed to create a customer. You can, but if you had a multi-stage process to achieve this, you might find the need to persist the customer data for later completion or for deployment to future orders. If all nav properties were implemented, you'd have to establish every Foreign Key and relational field on the save. That really just sets the data back into memory, which defeats the role of persistence.
So while it may seem cryptic in the actual execution at run time, I have found the best rule of thumb to use would be: if you are outputting data (reading into a View Model or Serializable Model) and need values before references, do not use virtual; If your scope is collecting data that may be incomplete or a need to search and not require every search parameter completed for a search, the code will make good use of reference, similar to using nullable value properties int? long?. Also, abstracting your business logic from your data collection until the need to inject it has many performance benefits, similar to instantiating an object and starting it at null. Entity Framework uses a lot of reflection and dynamics, which can degrade performance, and the need to have a flexible model that can scale to demand is critical to managing performance.
To me, that always made more sense than using overloaded tech jargon like proxies, delegates, handlers and such. Once you hit your third or fourth programming lang, it can get messy with these.
The virtual
keyword in C# enables a method or property to be overridden by child classes. For more information please refer to the MSDN documentation on the 'virtual' keyword
UPDATE: This doesn't answer the question as currently asked, but I'll leave it here for anyone looking for a simple answer to the original, non-descriptive question asked.
Source: Stackoverflow.com