简体   繁体   中英

C# Specify generic type parameter once and use it throughout class

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...

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>();
    }
}

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>();

Note also that T is specified on the method, not on the class and is known only inside the class.

This can also be a local function, ie, a function inside a method.

But to be clear: Generics are not dynamic, ie, you cannot use a runtime type (given as a variable or parameter of type System.Type ) as an argument for a generic type parameter.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM