[Solved] How to create a static variable shared amongst instances of closed constructed generic types?


There’s 3 ways that I can think of that would work for you:

  1. Create a non-generic base class holding the shared field(s)
  2. Create a non-generic separate class holding the shared field(s)
  3. Create a non-generic type that holds these shared values, and reuse this inside your generic ones

For the third one, since you say you don’t really want option 1 or 2, here’s an example:

public abstract class Shared
{
    private readonly static Dictionary<Guid, object> _Variables
        = new Dictionary<Guid, object>();

    protected void SetValue<T>(Guid key, T value)
    {
        lock (_Variables)
            _Variables[key] = value;
    }

    protected T GetValue<T>(Guid key)
    {
        object temp;
        lock (_Variables)
            if (!_Variables.TryGetValue(key, out temp))
                return default;

        return (T)temp;
    }
}

public class Shared<T> : Shared
{
    private readonly Guid _Key;

    public Shared(Guid key)
    {
        _Key = key;
    }

    public T Value
    {
        get => GetValue<T>(_Key);
        set => SetValue<T>(_Key, value);
    }
}

You would use this like this:

public class MyClass<T>
{
    private static readonly Shared<string> _Shared
        = new Shared<string>(Guid.Parse("521ecaba-2a5e-43f2-90e0-fda38a32618c"));

    public void Set(string value)
    {
        _Shared.Value = value;
    }

    public void Get()
    {
        Console.WriteLine(_Shared.Value);
    }
}

The Set/Get methods of that MyClass was used to test that a value set through one closed type is available through another, like this:

var mc1 = new MyClass<int>();
var mc2 = new MyClass<string>();

mc1.Set("Test");
mc2.Get();

This will output Test.

Even though all closed types of MyClass<T> will have their own static Shared<T> instance, the value contained in that instance will be backed by a shared dictionary that is shared between all types using this Shared<T> type.


Personally I would recommend going with the static non-generic base class though:

public abstract class MyClass
{
    protected static string _Shared;
}

public class MyClass<T> : MyClass
{
    public void Set(string value)
    {
        _Shared = value;
    }

    public void Get()
    {
        Console.WriteLine(_Shared);
    }
}

If you prefer the “base class”, that is, the type holding the shared value, to be unavailable, and not much with base classes (which wouldn’t work with structs either), you can easily just make it a completely separate class:

internal static class MyClassShared
{
    public static string Shared;
}

public class MyClass<T>
{
    public void Set(string value)
    {
        MyClassShared.Shared = value;
    }

    public void Get()
    {
        Console.WriteLine(MyClassShared.Shared);
    }
}

1

solved How to create a static variable shared amongst instances of closed constructed generic types?