Home > Software design >  C# Specify generic type parameter once and use it throughout class
C# Specify generic type parameter once and use it throughout class

Time:07-06

Let's say I have a class ClassWhichDoesThings which makes various calls to methods such as

DoSomething<TheTypeIWantToSpecifyOnce>();
DoAnotherThing<TheTypeIWantToSpecifyOnce>();
AndAnother<TheTypeIWantToSpecifyOnce>();

throughout the class.

Is it possible to specify the generic type in one place (like a variable but not determined at runtime) without anything outside of the class having to also pass a generic type (avoiding ClassWhichDoesThings<T>) such that the method calls become something like:

Type WriteTypeOnce = typeof(TheTypeIWantToSpecifyOnce);

DoSomething<WriteTypeOnce>();
DoAnotherThing<WriteTypeOnce>();
AndAnother<WriteTypeOnce>();

The objective here being that if I want to change the Type, I don't have to do a find and replace on 20 different method calls for example.

Essentially I want a generic class which specifies its own generic type privately.

Edit: In other words, I'm trying to better organise code which is completely private to a class but focuses on dealing with a single Type. For example, let's say I wanted to add the method:

public TheTypeIWantToSpecifyOnce CreateAThing(string input){ ... }

I want it to be very clear that this class focuses on TheTypeIWantToSpecifyOnce or T so that it's easy to write another method with T but without T being specified when creating the class...

CodePudding user response:

Depended on the case you can create internal generic method or class and use it, making the class itself basically a wrapper:

public class SomeClass
{
    private readonly int Data = 1; 
    private Generic<ActualType> Instance;

    public SomeClass()
    {
        Instance = new(this);
    }

    public int SomeMethod => Instance.SomeMethodImpl();
    public int SomeMethod1 => Instance.SomeMethodImpl2();

    private class Generic<TheTypeIWantToSpecifyOnce>
    {
        private readonly SomeClass _instance;

        // if needed - pass the parent class instance to reference it's internal data
        // if not - remove both ctors and 
        // just init with Generic<ActualType> Instance = new();
        public Generic(SomeClass instance) 
        {
            _instance = instance;
        }
        public int SomeMethodImpl() => DoSomething<TheTypeIWantToSpecifyOnce>();

        public int SomeMethodImpl2()
        {
            Console.WriteLine(_instance.Data); // use parent internal data if needed
            DoAnotherThing<TheTypeIWantToSpecifyOnce>();
            return AndAnother<TheTypeIWantToSpecifyOnce>();
        }
    }
}

Another approach can be using alias directive:

using TheTypeIWantToSpecifyOnce = System.Int32;
public class SomeClass
{
    public int SomeMethod => DoSomething<TheTypeIWantToSpecifyOnce>();
    public int SomeMethod1() 
    {
        DoAnotherThing<TheTypeIWantToSpecifyOnce>();
        return AndAnother<TheTypeIWantToSpecifyOnce>();
    }
}

CodePudding user response:

Yes, you can write a method with a type parameter

static void DoAllThings<T>()
{
    DoSomething<T>();
    DoAnotherThing<T>();
    AndAnother<T>();   
}

and call it with

DoAllThings<TheTypeIWantToSpecifyOnce>();

It can also be a local function.

  • Related