c# - How to implement a sealed, public nested class that can only be created by its enclosing class? -


goal

my goal implement sealed, public nested class can created enclosing class - without using reflection.

that means nested class cannot have public or internal constructors or public or internal static factory methods.

previous work

this post couple of years ago seems answer. (that entire thread has lot of information i'm trying achieve.)

how works quite straightforward: leverages fact nested class can access static fields of enclosing class, along static constructor nested class.

the enclosing class declares static func<nestedclasstype, nestedclassctorargtype> delegate returns instance of nested class, enclosing class can use delegate factory method.

the nested class has static constructor initialises enclosing class's static factory delegate delegate create instance of nested class.

the problem

unfortunately, can't work written in answer. reason static constructor nested class not called before enclosing class uses factory method, , there null-reference exception. (if @ sample program @ end of question see mean.)

my workaround

i have worked around problem follows:

  1. added nested class internal static initialise() method nothing.
  2. added enclosing class static constructor calls nested class's initialise() method.

this works fine, leaves bit of carbuncle in shape of internal static void initialise() method.

my questions

is there way avoid way of doing it? can't think i'm missing original post linked above. did misunderstand answer?

is there clever way force static constructor nested class run before call code tries create instance of nested class?

and there other problems approach?

(i'm aware can write public interface nested class, , return instead. question isn't solving way!)

the sample code

here's sample code. try running it, , print "test". try commenting-out line marked <--- if comment out, things won't work , run again.

using system;  namespace consoleapplication1 {     class program     {         static void main()         {             outer outer = new outer();             outer.inner item = outer.item("test");             console.writeline(item.text);         }     }      public sealed class outer     {         public inner item(string text)         {             return _nestedfactory(text);         }          // static constructor calls nested class's initialise() method, causes         // nested class's static constructor run, sets enclosing class's          // _nestedfactory field appropriately.          static outer()         {             inner.initialise(); // <--- if comment out, things won't work.         }          // class has private constructor.         // want class outer able create instances of it.          public sealed class inner         {             private inner(string value) // secret private constructor!             {                 text = value;             }              public string text { { return text; } }              static inner()             {                 _nestedfactory = text => new inner(text);             }              internal static void initialise(){}             readonly string text;         }          static func<string, inner> _nestedfactory;     } } 

you can use code if need force class constructor run without having reference type:

static outer() {     system.runtime.compilerservices.runtimehelpers.runclassconstructor(typeof (inner).typehandle); } 

Comments

Popular posts from this blog

linux - Does gcc have any options to add version info in ELF binary file? -

android - send complex objects as post php java -

charts - What graph/dashboard product is facebook using in Dashboard: PUE & WUE -