Static readonly field cannot be assigned to (except in static constructor) - c#

abstract class DirectiveNode
{
public static readonly RequirementOptions ArgumentOptions = RequirementOptions.Optional;
}
class IfNode : DirectiveNode
{
static IfNode()
{
ArgumentOptions = RequirementOptions.Required; // error here
}
I don't understand the problem. I thought static IfNode() was a static constructor? Why the error?
Just found this: Assigning to static readonly field of base class

You can only assign it in the static constructor of the same class.
By the way, it sounds like you expect the static field to contain different values depending on which derived class you are talking about. This is not how it works. Only a single instance of the field will exist and it's shared across all derived classes.

Unlike nonstatic constructors, a subclass's static constructor has no relationship with the parent static constructor. If you want the subclass to be able to change the ArgumentOptions value used by base class functions, consider a virtual property:
abstract class DirectiveNode
{
public virtual RequirementOptions ArgumentOptions
{
get { return RequirementOptions.Optional; }
}
}
class IfNode : DirectiveNode
{
public override RequirementOptions ArgumentOptions
{
get { return RequirementOptions.Required; }
}
}

Related

Cannot access inherited property if class has nested class of same name

I want to access a property of some class of mine, but get compiler error "CS0572 - Cannot reference a type through an expression".
I have the following setup
public interface IHelper {
void DoHelp();
}
public abstract class ClassWithHelperBase<THelper> where THelper : IHelper {
public THelper Helper { get; }
}
public class ClassWithHelper : ClassWithHelperBase<ClassWithHelper.Helper> {
// use a nested class, since there will be n classes deriving from ClassWithHelper and giving each helper a readable name (in this example ClassWithHelperHelper) is ugly
public class Helper : IHelper {
public static void SomeStaticMethod() { }
public void DoHelp() { }
}
}
public class Test {
private ClassWithHelper myClass;
public void DoTest() {
((ClassWithHelperBase<ClassWithHelper.Helper>) myClass).Helper.DoHelp(); // this works, but is ugly
myClass.Helper.DoHelp(); // what I want, but it's not working
//myClass.Helper.SomeStaticMethod(); // funnily IDE supposes static methods here even though the resulting code is invalid, since I am (obviously) not referencing the class type
}
}
The interface is unnecessary for reproduction, I added it for clarity.
Note: I do not want to call a static method, I just added it, to show the IDE mixes up the member and the class qualifier.
Is there a way to access the property Helper of myClass, without casting myClass or renaming the nested class?
Aka: Why can't the compiler distinguish the member and the nested class?
The problems is due to name collision between Helper class (type) and Helper property. Try this
public interface IHelper
{
void DoHelp();
}
public abstract class ClassWithHelperBase<THelper> where THelper : IHelper
{
public THelper Helper { get; set; }
}
public class ClassWithHelper : ClassWithHelperBase<ClassWithHelper.CHelper>
{
// use a nested class, since there will be n classes deriving from ClassWithHelper and giving each helper a readable name (in this example ClassWithHelperHelper) is ugly
public class CHelper : IHelper
{
public static void SomeStaticMethod() {}
public void DoHelp() { }
}
}
public class Test
{
private ClassWithHelper myClass;
public void DoTest() {
myClass.Helper.DoHelp();
ClassWithHelper.CHelper.SomeStaticMethod();
}
}
Here I renamed Helper class to the CHelper, so compiler can now distinguish class and property and thus the line myClass.Helper.DoHelp(); now works without cast.
If a "do not rename nested class" requirement is absolutely mandatory, then the problem may be also solved by renaming the Helper property in the base class to avoid name collision. However, I can't imagine better name for the property.
Unfortunately, for the static method, you can't reference myClass instance. So, you will need reference the whole type.

Explicitly call static constructor in base static constructor

This one's a little weird/complex and more just curiosity than anything.
I was looking for a way to make sure static calls from a base class could safely use static information set up in a derived class. I then noticed that C# allows me to call the derived class static constructor in the base class static constructor.
My question: Is is safe to call the derived class static constructor in the base class static constructor
Here is some sample code:
public abstract class Enumeration<TEnum, TValue>
where TEnum : Enumeration<TEnum, TValue> // << Note the CRTP-ish thing
where TValue: class
{
private static readonly Dictionary<string, Enumeration<TEnum, TValue>> Mapping = new Dictionary<string, Enumeration<TEnum, TValue>>();
public TValue Value { get; }
public string Name { get; }
// Base class calling derived static constructor. This sets up "Mapping" with derived class enumerations
static Enumeration()
{
System.Runtime.CompilerServices.RuntimeHelpers.RunClassConstructor(typeof(TEnum).TypeHandle);
}
// Static member "Mapping" filled using this constructor when derived class statics are initialized
protected Enumeration(TValue enumValue, string name)
{
Value = enumValue;
Name = name;
Mapping.Add(name, this);
}
// Uses "Mapping", so "Mappings" needs to be filled before this is called.
protected static IEnumerable<TEnum> All => Mapping.Values.AsEnumerable().Cast<TEnum>();
public override string ToString() { return Name; }
}
public sealed class DerivedEnum : Enumeration<DerivedEnum, String>
{
// This static member will input itself into the static "Mapping" in the base class
public static readonly DerivedEnum A = new DerivedEnum("A", "A");
private DerivedEnum(string val, string name) : base(val, name) {}
}
I have done several basic tests and it doesn't seem to break. Is there a way this could break?
Here is a fiddle if you need to... fiddle: https://dotnetfiddle.net/mREPyL
Also, my code is inspired by this answer. I wanted to see if I could get the derived classes more succinct.

Instance Member issue concerning a public method in a public class

Inside of a public class:
public static class LogReporting
I have the following method:
public void RunTimerJobs()
{
SPAdministrationWebApplication centralAdmin = SPAdministrationWebApplication.Local;
try
{
foreach (SPService service in centralAdmin.Farm.Services)
{
Guid traceGuid = new Guid("d3beda82-38f4-4bc7-874f-ad45cebc9b35");
Guid eventGuid = new Guid("3ea057b3-0391-4c33-ac8d-412aecdda97d");
var traceJob =
from jobDefinition in service.JobDefinitions
where jobDefinition.Id == traceGuid
select jobDefinition;
if (traceJob != null && traceJob.Count() == 1)
{
traceJob.First().RunNow();
}
var eventJob =
from jobDefinition in service.JobDefinitions
where jobDefinition.Id == eventGuid
select jobDefinition;
if (eventJob != null && eventJob.Count() == 1)
{
eventJob.First().RunNow();
}
}
}
catch (Exception ex)
{
//Loggers.SharePointLogger logger = new Loggers.SharePointLogger();
//logger.WriteTrace(ex.Message, LogProduct.MonitoringView, LogTraceSeverity.Unexpected);
}
However it will not allow me to compile citing that RunTimerJobs() "cannot declare instance members in a static class"
To my knowledge, none of the 'instance members' I declare are able to be labeled as static, so is there just a fundamental issue with the setup (i.e. a static class) or am I missing some little snippet?
Your class is static thus you cannot have any instance members because you will never instantiate the class.
To be able to use the RunTimerJobs() method you would need to create an instance of the LogReporting class, i.e.
LogReporting logReporting = new LogReporting();
logReporting.RunTimerJobs();
This obviously won't work though because your class is defined as static and you cannot create instances of it.
Either make your method static or remove the static keyword from your class declaration - depending on what you require.
I see no instance related logic in your method so it should be safe to mark it as static.
Remember
Classes can have a mixture of instance and static members as long as the class isn't marked static.
And
Only mark classes as static when you know that ALL members (properties, methods etc...) will be static as well.
The compiler's being pretty clear here. You're declaring a static class, and static classes can only contain static members. So this is okay:
public class NonStaticClass
{
public void InstanceMethod() {}
}
And this is okay:
public static class StaticClass
{
public static void StaticMethod() {}
}
But this isn't:
public static class StaticClass
{
public void InstanceMethod() {}
}
If you wanted to declare instance members, why did you declare LogReporting as a static class?
When class marked as static, then all it's members should be static (instances creation is not allowed). You can read more about static classes on msdn.
So, if you want to have instance (non-static) method, then remove static keyword from class definition:
public class LogReporting
{
public void RunTimerJobs()
{
//...
}
}
In this case you should create LogReporting instance to call your method:
LogReporting log = new LogReporting();
log.RunTimerJobs();
Another option for you - making your method static:
public static class LogReporting
{
public static void RunTimerJobs()
{
//...
}
}
In this case you don't need instance of LogReporting:
LogReporting.RunTimerJobs();
Did you try:
public static void RunTimerJobs()
For a static class, the members must also be static. If you are unable make the members static, then you must make the class non-static as well.
It's generally a good idea to use non-static classes if you can, as static classes increase the complexity of unit testing as they cannot be mocked out easily. Of course if you have a legitimate need to use a static class, then by all means do so.

What's the best way to ensure a base class's static constructor is called?

The documentation on static constructors in C# says:
A static constructor is used to
initialize any static data, or to
perform a particular action that needs
performed once only. It is called
automatically before the first
instance is created or any static
members are referenced.
That last part (about when it is automatically called) threw me for a loop; until reading that part I thought that by simply accessing a class in any way, I could be sure that its base class's static constructor had been called. Testing and examining the documentation have revealed that this is not the case; it seems that the static constructor for a base class is not guaranteed to run until a member of that base class specifically is accessed.
Now, I guess in most cases when you're dealing with a derived class, you would construct an instance and this would constitute an instance of the base class being created, thus the static constructor would be called. But if I'm only dealing with static members of the derived class, what then?
To make this a bit more concrete, I thought that the code below would work:
abstract class TypeBase
{
static TypeBase()
{
Type<int>.Name = "int";
Type<long>.Name = "long";
Type<double>.Name = "double";
}
}
class Type<T> : TypeBase
{
public static string Name { get; internal set; }
}
class Program
{
Console.WriteLine(Type<int>.Name);
}
I assumed that accessing the Type<T> class would automatically invoke the static constructor for TypeBase; but this appears not to be the case. Type<int>.Name is null, and the code above outputs the empty string.
Aside from creating some dummy member (like a static Initialize() method that does nothing), is there a better way to ensure that a base type's static constructor will be called before any of its derived types is used?
If not, then... dummy member it is!
You may call static constructor explicity, so you will not have to create any methods for initialization:
System.Runtime.CompilerServices.RuntimeHelpers.RunClassConstructor(typeof (TypeBase).TypeHandle);
You may call it in static constructor of derived class.
As others have noted, your analysis is correct. The spec is implemented quite literally here; since no member of the base class has been invoked and no instance has been created, the static constructor of the base class is not called. I can see how that might be surprising, but it is a strict and correct implementation of the spec.
I don't have any advice for you other than "if it hurts when you do that, don't do that." I just wanted to point out that the opposite case can also bite you:
class Program
{
static void Main(string[] args)
{
D.M();
}
}
class B
{
static B() { Console.WriteLine("B"); }
public static void M() {}
}
class D: B
{
static D() { Console.WriteLine("D"); }
}
This prints "B" despite the fact that "a member of D" has been invoked. M is a member of D solely by inheritance; the CLR has no way of distinguishing whether B.M was invoked "through D" or "through B".
The rules here are very complex, and between CLR 2.0 and CLR 4.0 they actually changed in subtle and interesting ways, that IMO make most "clever" approaches brittle between CLR versions. An Initialize() method also might not do the job in CLR 4.0 if it doesn't touch the fields.
I would look for an alternative design, or perhaps use regular lazy initialization in your type (i.e. check a bit or a reference (against null) to see if it has been done).
In all of my testing, I was only able to get a call to a dummy member on the base to cause the base to call its static constructor as illustrated:
class Base
{
static Base()
{
Console.WriteLine("Base static constructor called.");
}
internal static void Initialize() { }
}
class Derived : Base
{
static Derived()
{
Initialize(); //Removing this will cause the Base static constructor not to be executed.
Console.WriteLine("Derived static constructor called.");
}
public static void DoStaticStuff()
{
Console.WriteLine("Doing static stuff.");
}
}
class Program
{
static void Main(string[] args)
{
Derived.DoStaticStuff();
}
}
The other option was including a static read-only member in the derived typed that did the following:
private static readonly Base myBase = new Base();
This however feels like a hack (although so does the dummy member) just to get the base static constructor to be called.
I almost alway regret relying on something like this. Static methods and classes can limit you later on. If you wanted to code some special behavior for your Type class later you would be boxed in.
So here is a slight variation on your approach. It is a bit more code but it will allow you to have a custom Type defined later that lets you do custom things.
abstract class TypeBase
{
private static bool _initialized;
protected static void Initialize()
{
if (!_initialized)
{
Type<int>.Instance = new Type<int> {Name = "int"};
Type<long>.Instance = new Type<long> {Name = "long"};
Type<double>.Instance = new Type<double> {Name = "double"};
_initialized = true;
}
}
}
class Type<T> : TypeBase
{
private static Type<T> _instance;
public static Type<T> Instance
{
get
{
Initialize();
return _instance;
}
internal set { _instance = value; }
}
public string Name { get; internal set; }
}
Then later when you get to adding a virtual method to Type and want a special implementation for Type you can implement thus:
class TypeInt : Type<int>
{
public override string Foo()
{
return "Int Fooooo";
}
}
And then hook it up by changing
protected static void Initialize()
{
if (!_initialized)
{
Type<int>.Instance = new TypeInt {Name = "int"};
Type<long>.Instance = new Type<long> {Name = "long"};
Type<double>.Instance = new Type<double> {Name = "double"};
_initialized = true;
}
}
My advice would be to avoid static constructors - it is easy to do. Also avoid static classes and where possible static members. I am not saying never, just sparingly. Prefer a singleton of a class to a static.
Just an idea, you can do something like this:
abstract class TypeBase
{
static TypeBase()
{
Type<int>.Name = "int";
Type<long>.Name = "long";
Type<double>.Name = "double";
}
}
class Type<T> : TypeBase
{
static Type()
{
new Type<object>();
}
public static string Name { get; internal set; }
}
class Program
{
Console.WriteLine(Type<int>.Name);
}

How to restrict access to nested class member to enclosing class?

Is it possible to specify that members of a nested class can be accessed by the enclosing class, but not other classes ?
Here's an illustration of the problem (of course my actual code is a bit more complex...) :
public class Journal
{
public class JournalEntry
{
public JournalEntry(object value)
{
this.Timestamp = DateTime.Now;
this.Value = value;
}
public DateTime Timestamp { get; private set; }
public object Value { get; private set; }
}
// ...
}
I would like to prevent client code from creating instances of JournalEntry, but Journal must be able to create them. If I make the constructor public, anyone can create instances... but if I make it private, Journal won't be able to !
Note that the JournalEntry class must be public, because I want to be able to expose existing entries to client code.
Any suggestion would be appreciated !
UPDATE: Thanks everyone for your input, I eventually went for the public IJournalEntry interface, implemented by a private JournalEntry class (despite the last requirement in my question...)
Actually there is a complete and simple solution to this problem that doesn't involve modifying the client code or creating an interface.
This solution is actually faster than the interface-based solution for most cases, and easier to code.
public class Journal
{
private static Func<object, JournalEntry> _newJournalEntry;
public class JournalEntry
{
static JournalEntry()
{
_newJournalEntry = value => new JournalEntry(value);
}
private JournalEntry(object value)
{
...
If your class is not too complex, you could either use an interface which is publicly visible and make the actual implementing class private, or you could make a protected constructor for the JornalEntry class and have a private class JornalEntryInstance derived from JornalEntry with a public constructor which is actually instantiated by your Journal.
public class Journal
{
public class JournalEntry
{
protected JournalEntry(object value)
{
this.Timestamp = DateTime.Now;
this.Value = value;
}
public DateTime Timestamp { get; private set; }
public object Value { get; private set; }
}
private class JournalEntryInstance: JournalEntry
{
public JournalEntryInstance(object value): base(value)
{ }
}
JournalEntry CreateEntry(object value)
{
return new JournalEntryInstance(value);
}
}
If your actual class is too complex to do either of that and you can get away with the constructor being not completely invisible, you can make the constructor internal so it is only visible in the assembly.
If that too is infeasible, you can always make the constructor private and use reflection to call it from your journal class:
typeof(object).GetConstructor(new Type[] { }).Invoke(new Object[] { value });
Now that I think about it, another possibility would use a private delegate in the containing class which is set from the inner class
public class Journal
{
private static Func<object, JournalEntry> EntryFactory;
public class JournalEntry
{
internal static void Initialize()
{
Journal.EntryFactory = CreateEntry;
}
private static JournalEntry CreateEntry(object value)
{
return new JournalEntry(value);
}
private JournalEntry(object value)
{
this.Timestamp = DateTime.Now;
this.Value = value;
}
public DateTime Timestamp { get; private set; }
public object Value { get; private set; }
}
static Journal()
{
JournalEntry.Initialize();
}
static JournalEntry CreateEntry(object value)
{
return EntryFactory(value);
}
}
This should give you your desired visibility levels without needing to resort on slow reflection or introducing additional classes / interfaces
Make JournalEntry a private nested type. Any public members will be visible only to the enclosing type.
public class Journal
{
private class JournalEntry
{
}
}
If you need to make JournalEntry objects available to other classes, expose them via a public interface:
public interface IJournalEntry
{
}
public class Journal
{
public IEnumerable<IJournalEntry> Entries
{
get { ... }
}
private class JournalEntry : IJournalEntry
{
}
}
A simpler approach is to just use an internal constructor, but make the caller prove who they are by supplying a reference that only the legitimate caller could know (we don't need to be concerned about non-public reflection, because if the caller has access to non-public reflection then we've already lost the fight - they can access a private constructor directly); for example:
class Outer {
// don't pass this reference outside of Outer
private static readonly object token = new object();
public sealed class Inner {
// .ctor demands proof of who the caller is
internal Inner(object token) {
if (token != Outer.token) {
throw new InvalidOperationException(
"Seriously, don't do that! Or I'll tell!");
}
// ...
}
}
// the outer-class is allowed to create instances...
private static Inner Create() {
return new Inner(token);
}
}
In this case you could either:
Make the constructor internal - this stops those outside this assembly creating new instances or...
Refactor the JournalEntry class to use a public interface and make the actual JournalEntry class private or internal. The interface can then be exposed for collections while the actual implementation is hidden.
I mentioned internal as a valid modifier above however depending on your requirements, private may be the better suited alternative.
Edit: Sorry I mentioned private constructor but you've already dealt with this point in your question. My apologies for not reading it correctly!
For generic nested class =)
I know this is an old question and it has already an accepted answer, nevertheless for those google swimmers who may have a similar scenario to mine this answer may provide some help.
I came across this question for I needed to implement the same feature as the OP. For my first scenario this and this answers worked just fine. Nevertheless I needed also to expose a nested generic class. The problem is that you can not expose a delegate type field (the factory field) with opened generic parameters without making your own class generic, but obviously this is not what we want, so, here is my solution for such scenario:
public class Foo
{
private static readonly Dictionary<Type, dynamic> _factories = new Dictionary<Type, dynamic>();
private static void AddFactory<T>(Func<Boo<T>> factory)
=> _factories[typeof(T)] = factory;
public void TestMeDude<T>()
{
if (!_factories.TryGetValue(typeof(T), out var factory))
{
Console.WriteLine("Creating factory");
RuntimeHelpers.RunClassConstructor(typeof(Boo<T>).TypeHandle);
factory = _factories[typeof(T)];
}
else
{
Console.WriteLine("Factory previously created");
}
var boo = (Boo<T>)factory();
boo.ToBeSure();
}
public class Boo<T>
{
static Boo() => AddFactory(() => new Boo<T>());
private Boo() { }
public void ToBeSure() => Console.WriteLine(typeof(T).Name);
}
}
We have Boo as our internal nested class with a private constructor and we mantain on our parent class a dictionary with these generic factories taking advantage of dynamic. So, each time TestMeDude is called, Foo searches for whether the factory for T has already been created, if not it creates it calling nested class' static constructor.
Testing:
private static void Main()
{
var foo = new Foo();
foo.TestMeDude<string>();
foo.TestMeDude<int>();
foo.TestMeDude<Foo>();
foo.TestMeDude<string>();
Console.ReadLine();
}
The output is:
The solution Grizzly suggested does make it a bit hard to create the nested class somewhere else but not impossible,like Tim Pohlmann wrote someone can still inherit it and use the inheriting class ctor.
I'm taking advantage of the fact that nested class can access the container private properties, so the container asks nicely and the nested class gives access to the ctor.
public class AllowedToEmailFunc
{
private static Func<long, EmailPermit> CreatePermit;
public class EmailPermit
{
public static void AllowIssuingPermits()
{
IssuegPermit = (long userId) =>
{
return new EmailPermit(userId);
};
}
public readonly long UserId;
private EmailPermit(long userId)
{
UserId = userId;
}
}
static AllowedToEmailFunc()
{
EmailPermit.AllowIssuingPermits();
}
public static bool AllowedToEmail(UserAndConf user)
{
var canEmail = true; /// code checking if we can email the user
if (canEmail)
{
return IssuegPermit(user.UserId);
}
else
{
return null
}
}
}
This solution is not something I would do on a regular day on the job, not because it will lead to problems in other places but because it's unconventional (I've never seen it before) so it might cause other developers pain .

Categories

Resources