Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Inferring type parameter in method

I have a hierarchy of classes in my C# library representing domain entities, all eventually descending from a root abstract class named DomainEntity. Some examples are Package or Customer. I employ Create() factory methods in each class to create instances. I also have a generic processor class Processor<T> where T: DomainEntity. This processor class also uses a factory method to be instantiated and performs business logic that depends on the specific class, hence its type parameter. Using this library, I can for example write code like this:

var pkg = Package.Create(/* various arguments */);
var pro = Processor<Package>.Create(pkg);
pro.DoStuff();

So far so good. Now I would like to write a method in DomainEntity that returns a processor for any particular domain entity. Something like this:

public Processor<T> CreateProcessor<T>()
    where T: DomainEntity
{
    var pro = Processor<T>.Create((T)this);
    return pro;
}

This method can be used like this:

var pkg = Package.Create(/* various arguments */);
var pro = pkg.CreateProcessor<Package>();
pro.DoStuff();

This works fine, but I find the Package reference in the call to CreateProcessor() a bit redundant, as I am calling the method on an instance of Package and therefore there is no ambiguity as to which class the type parameter should refer. However, this will not compile:

var pkg = new Package(/* various arguments */);
var pro = pkg.CreateProcessor(); //<-- this does not compile.
pro.DoStuff();

My question is:

Is there an alternative way to write the CreateProcessor() method so that the type parameter is inferred by the compiler from the object it is being called on?

I can provide a complete working Visual Studio project on demand.

like image 933
CesarGon Avatar asked Sep 12 '26 22:09

CesarGon


1 Answers

You just need to create a generic extension method:

public static class EntityExtensions
{
    public static Processor<T> CreateProcessor<T>(this T entity)
        where T : DomainEntity
        => new Processor<T>(entity);
}

That should allow you to use type inference just fine:

var package = new Package();
var processor = package.CreateProcessor();

That second line is equivalent to:

var processor = EntityExtensions.CreateProcessor<Package>(package);
like image 72
Jon Skeet Avatar answered Sep 15 '26 11:09

Jon Skeet