Is there a good way to handle private static fields in a generic type in C #?
I am trying to figure out a way that I can use fields private
static
in general class
. This is the obvious way to do it ( fiddle ). It won't compile because it is Field
not available in BaseChild
, and ideally I would not want it to be available there:
public class Base<T>
{
private static readonly string Field = "field";
public Base()
{
Console.WriteLine(Field);
}
}
public class BaseChild : Base<string>
{
public BaseChild()
{
Console.WriteLine(Field);
}
}
The problem with this solution is that there is a different one for each generic type Field
and not a common one.
I saw this answer where it says that JetBrains recommends a field solution static
for generic types:
If you need to have a static field shared between instances with different generating arguments, define a base class that is not shared to hold your static members, and then set your type to a generic type of that type.
This makes sense for the case when you have tags public
or protected
static
in a class base
that you want to pass through any child class
, like this example ( fiddle ):
public abstract class Base
{
protected static readonly string Field = "field";
}
public class Base<T> : Base
{
public Base()
{
Console.WriteLine(Field);
}
}
public class BaseChild : Base<string>
{
public BaseChild()
{
Console.WriteLine(Field);
}
}
However, what about a case where you want to use a field private
static
? I would guess that this is not possible, since it private
means only available for class
which it declared, and I think that since the generic class
is really just a template to create class
, then any private
field could only be accessible to everyone class
, but not to all classes created template.
Should I just put the field private
in a generic class (example 1) and accept it as at least a workable solution for what I want, or is there another way I can do this?
source to share
This is what I came up with, I think it actually does what I want, better than the original example I asked in my question. It shares one static field for all generic types, and it is not accessible to children of the base class Base.
public static class Base
{
private static string Field = "field";
public class Base2<T>
{
public Base2()
{
// Field is accessible here, but is the same across all generic classes
Console.WriteLine(Field);
}
}
}
public class BaseChild : Base.Base2<string>
{
public BaseChild()
{
//Field is not accessible here, and I don't really want it to be
//Console.WriteLine(Field);
}
}
source to share
First, private
it does exactly what it did: to restrict access to only the type in which it was declared. Be aware that instances of a generic type are different types. You shouldn't get around this.
If I understand your question correctly, you can accomplish what you want using protected
with an additional level of inheritance:
class EvenMoreBase
{
protected static readonly string Field = "field";
}
class Base<T> : EvenMoreBase
{
public Base()
{
Console.WriteLine(Field);
}
}
class BaseChild : Base<string>
{
public BaseChild()
{
Console.WriteLine(Field);
}
}
Now each of yours Base<T>
will have the same instance Field
.
source to share
You are correct in your thoughts on private
the base class. Whether it is static or not makes no difference.
Here's a small example:
using System;
public class Program
{
public static void Main()
{
Bar b = new Bar(); // Prints "Foo"
// Console.WriteLine(Foo.BaseField); // Compile error
}
}
public class Foo
{
protected static readonly string BaseeField = "Foo";
}
public class Bar : Foo
{
public Bar()
{
Console.WriteLine(Foo.BaseeField);
}
}
Protected labeling is useful if you want only your children to be able to access it. And leave it static
to how to keep only one instance for all children of the base class Foo
.
source to share