Tag Archives: Covariance

Configuring your models with Entity Framework

One of the tricks I’ve used for a while when setting EF up in a project, is to use inheritance in order to share code, but not objects, across the business and data layers of the application.

Let’s take the following example, as shown above:

namespace MyProject.Models
    public class ResourceModel

And now the data layer:

namespace MyProject.Data.Resources
    public class ResourceEntity : ResourceModel

This gives us a number of advantages: the code is shared between the objects, but the two objects are not the same. However, until recently, this presented an issue. Imagine that we had a property in the model that looked like this:

public TagModel[] Tags { get; } 

TagModel itself might have a similar inheritance structure; however, how would you return that from the data layer – since the inheritance would force it to return the same type.

Covariance return type

Fortunately, since C# 9 you can return covariants (Covariance is basically the idea that you can substitute a sub-type for a class).

What this means is that you can override the relevant property in the sub class (the data layer). First, you’ll need to make the property virtual:

    public class ResourceModel
        public virtual TagModel[] Tags { get; } 

And then just override it:

    public class ResourceEntity : ResourceModel
        public int Id { get; set; }

        public override TagEntity[] Tags { get; }

You can’t use anything like a List here, because (for example) a List of TagEntity has no relationship to a List of TagModel.

Hope this helps.





Casting a C# Object From its Parent

Have you ever tried to do something akin to the following:

public void ConvertClassToSubClass_Converts()
    // Arrange
    var parentClass = new SimpleTestClass();
    parentClass.Property1 = "test";
    // Act
    var childClass = parentClass as SimpleTestSubClass;
    // Assert
    Assert.Equal("test", childClass.Property1);

This is a simple Xunit (failing) test. The reason is fails is because you (or I) am trying to cast a general type to a specific, and C# is complaining that this may not be possible; consequently, you will get null (or for a hard cast, you’ll get an InvalidCastException.

Okay, that makes sense. After all, parentClass could actually be a SimpleTestSubClass2 and, as a result, C# is being safe because there’s (presumably – I don’t work for MS) too many possibilities for edge cases.

This is, however, a solvable problem; there are a few ways to do it, but you can simply use reflection:

public TNewClass CastAsClass<TNewClass>() where TNewClass : class
    var newObject = Activator.CreateInstance<TNewClass>();
    var newProps = typeof(TNewClass).GetProperties();
    foreach (var prop in newProps)
        if (!prop.CanWrite) continue;
        var existingPropertyInfo = typeof(TExistingClass).GetProperty(prop.Name);
        if (existingPropertyInfo == null || !existingPropertyInfo.CanRead) continue;
        var value = existingPropertyInfo.GetValue(_existingClass);
        prop.SetValue(newObject, value, null);
    return newObject;

This code will effectively transfer any class over to any other class.

If you’d rather use an existing library, you can always use this one. It’s also Open Source on Git Hib.