Set readonly fields in a constructor local function c#2019 Community Moderator ElectionCalling the base constructor in C#What are the benefits to marking a field as `readonly` in C#?Assigning to static readonly field of base classReadonly field that could be assigned a value outside constructorAssigning a value to an inherited readonly field?assign value of readonly variable in private method called only by constructorsreadonly-fields as targets from subclass constructorsWhy do I NOT get warnings about uninitialized readonly fields?Why can't I serialize readonly fields with XmlSerializer?child class constructor cannot assign to readonly variable inside

Why is the President allowed to veto a cancellation of emergency powers?

Why does a Star of David appear at a rally with Francisco Franco?

Have the tides ever turned twice on any open problem?

Is there a hypothetical scenario that would make Earth uninhabitable for humans, but not for (the majority of) other animals?

My adviser wants to be the first author

How do I hide Chekhov's Gun?

Python if-else code style for reduced code for rounding floats

Instead of a Universal Basic Income program, why not implement a "Universal Basic Needs" program?

Bach's Toccata and Fugue in D minor breaks the "no parallel octaves" rule?

Brexit - No Deal Rejection

Life insurance that covers only simultaneous/dual deaths

Book about superhumans hiding among normal humans

What is a ^ b and (a & b) << 1?

This word with a lot of past tenses

Have researchers managed to "reverse time"? If so, what does that mean for physics?

I am confused as to how the inverse of a certain function is found.

Min function accepting varying number of arguments in C++17

Why does overlay work only on the first tcolorbox?

If I can solve Sudoku, can I solve the Travelling Salesman Problem (TSP)? If so, how?

How to write cleanly even if my character uses expletive language?

Why Choose Less Effective Armour Types?

Converting a variable frequency to TTL HIGH and LOW levels, based on a fixed (possible non-fixed?) frequency

How to terminate ping <dest> &

Are all passive ability checks floors for active ability checks?



Set readonly fields in a constructor local function c#



2019 Community Moderator ElectionCalling the base constructor in C#What are the benefits to marking a field as `readonly` in C#?Assigning to static readonly field of base classReadonly field that could be assigned a value outside constructorAssigning a value to an inherited readonly field?assign value of readonly variable in private method called only by constructorsreadonly-fields as targets from subclass constructorsWhy do I NOT get warnings about uninitialized readonly fields?Why can't I serialize readonly fields with XmlSerializer?child class constructor cannot assign to readonly variable inside










10















The following does not compile.



public class A

private readonly int i;

public A()

void SetI()

i = 10;


SetI();




It fails with this error:




CS0191 A readonly field cannot be assigned to (except in a constructor or a variable initializer)




Technically are we not in the constructor still, since the visibility of the local function is limited, so I'm wondering why this does not compile.










share|improve this question



















  • 6





    The compiler turns the SetI local function into a separate class-level method. Since this separate class-level method is not a constructor, you are not allowed to assign to readonly fields from it.

    – canton7
    yesterday






  • 6





    @canton7 that is the answer. Why not write it as one?

    – Jamiec
    yesterday











  • If you could do this then the variable could no longer be called readonly. By definition, it can only be set once, during construction or with an initializer.

    – Andy G
    yesterday











  • Probably the local method could be called using reflection, which might allow modification of the readonly field after construction, so that's why they forbid it..?

    – Thomas Hilbert
    yesterday






  • 2





    There are two obvious workarounds if you do want this, incidentally: either make SetI return the desired value instead of assigning it directly, or use an out parameter. Both involve still doing the actual assignments in the constructor itself, of course. Because local functions are documented to be private methods, just with different scope rules, this is somewhat consistent. It would not technically be possible for C# to support this without a (rather obnoxious) change in the runtime to establish a "readonly path" of callers -- not really worth it.

    – Jeroen Mostert
    yesterday
















10















The following does not compile.



public class A

private readonly int i;

public A()

void SetI()

i = 10;


SetI();




It fails with this error:




CS0191 A readonly field cannot be assigned to (except in a constructor or a variable initializer)




Technically are we not in the constructor still, since the visibility of the local function is limited, so I'm wondering why this does not compile.










share|improve this question



















  • 6





    The compiler turns the SetI local function into a separate class-level method. Since this separate class-level method is not a constructor, you are not allowed to assign to readonly fields from it.

    – canton7
    yesterday






  • 6





    @canton7 that is the answer. Why not write it as one?

    – Jamiec
    yesterday











  • If you could do this then the variable could no longer be called readonly. By definition, it can only be set once, during construction or with an initializer.

    – Andy G
    yesterday











  • Probably the local method could be called using reflection, which might allow modification of the readonly field after construction, so that's why they forbid it..?

    – Thomas Hilbert
    yesterday






  • 2





    There are two obvious workarounds if you do want this, incidentally: either make SetI return the desired value instead of assigning it directly, or use an out parameter. Both involve still doing the actual assignments in the constructor itself, of course. Because local functions are documented to be private methods, just with different scope rules, this is somewhat consistent. It would not technically be possible for C# to support this without a (rather obnoxious) change in the runtime to establish a "readonly path" of callers -- not really worth it.

    – Jeroen Mostert
    yesterday














10












10








10








The following does not compile.



public class A

private readonly int i;

public A()

void SetI()

i = 10;


SetI();




It fails with this error:




CS0191 A readonly field cannot be assigned to (except in a constructor or a variable initializer)




Technically are we not in the constructor still, since the visibility of the local function is limited, so I'm wondering why this does not compile.










share|improve this question
















The following does not compile.



public class A

private readonly int i;

public A()

void SetI()

i = 10;


SetI();




It fails with this error:




CS0191 A readonly field cannot be assigned to (except in a constructor or a variable initializer)




Technically are we not in the constructor still, since the visibility of the local function is limited, so I'm wondering why this does not compile.







c# constructor compiler-errors readonly local-functions






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited yesterday









Kris Harper

2,99152865




2,99152865










asked yesterday









iliasilias

1,20421729




1,20421729







  • 6





    The compiler turns the SetI local function into a separate class-level method. Since this separate class-level method is not a constructor, you are not allowed to assign to readonly fields from it.

    – canton7
    yesterday






  • 6





    @canton7 that is the answer. Why not write it as one?

    – Jamiec
    yesterday











  • If you could do this then the variable could no longer be called readonly. By definition, it can only be set once, during construction or with an initializer.

    – Andy G
    yesterday











  • Probably the local method could be called using reflection, which might allow modification of the readonly field after construction, so that's why they forbid it..?

    – Thomas Hilbert
    yesterday






  • 2





    There are two obvious workarounds if you do want this, incidentally: either make SetI return the desired value instead of assigning it directly, or use an out parameter. Both involve still doing the actual assignments in the constructor itself, of course. Because local functions are documented to be private methods, just with different scope rules, this is somewhat consistent. It would not technically be possible for C# to support this without a (rather obnoxious) change in the runtime to establish a "readonly path" of callers -- not really worth it.

    – Jeroen Mostert
    yesterday













  • 6





    The compiler turns the SetI local function into a separate class-level method. Since this separate class-level method is not a constructor, you are not allowed to assign to readonly fields from it.

    – canton7
    yesterday






  • 6





    @canton7 that is the answer. Why not write it as one?

    – Jamiec
    yesterday











  • If you could do this then the variable could no longer be called readonly. By definition, it can only be set once, during construction or with an initializer.

    – Andy G
    yesterday











  • Probably the local method could be called using reflection, which might allow modification of the readonly field after construction, so that's why they forbid it..?

    – Thomas Hilbert
    yesterday






  • 2





    There are two obvious workarounds if you do want this, incidentally: either make SetI return the desired value instead of assigning it directly, or use an out parameter. Both involve still doing the actual assignments in the constructor itself, of course. Because local functions are documented to be private methods, just with different scope rules, this is somewhat consistent. It would not technically be possible for C# to support this without a (rather obnoxious) change in the runtime to establish a "readonly path" of callers -- not really worth it.

    – Jeroen Mostert
    yesterday








6




6





The compiler turns the SetI local function into a separate class-level method. Since this separate class-level method is not a constructor, you are not allowed to assign to readonly fields from it.

– canton7
yesterday





The compiler turns the SetI local function into a separate class-level method. Since this separate class-level method is not a constructor, you are not allowed to assign to readonly fields from it.

– canton7
yesterday




6




6





@canton7 that is the answer. Why not write it as one?

– Jamiec
yesterday





@canton7 that is the answer. Why not write it as one?

– Jamiec
yesterday













If you could do this then the variable could no longer be called readonly. By definition, it can only be set once, during construction or with an initializer.

– Andy G
yesterday





If you could do this then the variable could no longer be called readonly. By definition, it can only be set once, during construction or with an initializer.

– Andy G
yesterday













Probably the local method could be called using reflection, which might allow modification of the readonly field after construction, so that's why they forbid it..?

– Thomas Hilbert
yesterday





Probably the local method could be called using reflection, which might allow modification of the readonly field after construction, so that's why they forbid it..?

– Thomas Hilbert
yesterday




2




2





There are two obvious workarounds if you do want this, incidentally: either make SetI return the desired value instead of assigning it directly, or use an out parameter. Both involve still doing the actual assignments in the constructor itself, of course. Because local functions are documented to be private methods, just with different scope rules, this is somewhat consistent. It would not technically be possible for C# to support this without a (rather obnoxious) change in the runtime to establish a "readonly path" of callers -- not really worth it.

– Jeroen Mostert
yesterday






There are two obvious workarounds if you do want this, incidentally: either make SetI return the desired value instead of assigning it directly, or use an out parameter. Both involve still doing the actual assignments in the constructor itself, of course. Because local functions are documented to be private methods, just with different scope rules, this is somewhat consistent. It would not technically be possible for C# to support this without a (rather obnoxious) change in the runtime to establish a "readonly path" of callers -- not really worth it.

– Jeroen Mostert
yesterday













1 Answer
1






active

oldest

votes


















16














The compiler turns the SetI local function into a separate class-level method. Since this separate class-level method is not a constructor, you are not allowed to assign to readonly fields from it.



So the compiler takes this:



public class A

private readonly int i;

public A()

void SetI()

i = 10;


SetI();




and turns it into this:



public class A

private readonly int i;

public A()

<.ctor>g__SetI

[CompilerGenerated]
private void <.ctor>g__SetI


(SharpLab. I left off the readonly so it would compile.)



As you can see, it's trying to assign i from the method <.ctor>g__SetI|1_0(), which isn't a constructor.



Unfortunately the C# 7.0 language specification hasn't yet been published, so I can't quote it.



Exactly the same happens if you try and use a delegate:



public class A

private readonly int i;

public A()

Action setI = () => i = 10;

setI();




Gets compiled to:



public class A

private readonly int i;

public A()

Action action = <.ctor>b__1_0;
action();


[CompilerGenerated]
private void <.ctor>b__1_0()

i = 10;




(SharpLab, again with the readonly.)



... which likewise fails to compile.






share|improve this answer

























  • Thanks @canton7, I am looking forward to the c#7/8 language specification when/if it arrives.

    – ilias
    yesterday











Your Answer






StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");

StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);

else
createEditor();

);

function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);



);













draft saved

draft discarded


















StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55181639%2fset-readonly-fields-in-a-constructor-local-function-c-sharp%23new-answer', 'question_page');

);

Post as a guest















Required, but never shown

























1 Answer
1






active

oldest

votes








1 Answer
1






active

oldest

votes









active

oldest

votes






active

oldest

votes









16














The compiler turns the SetI local function into a separate class-level method. Since this separate class-level method is not a constructor, you are not allowed to assign to readonly fields from it.



So the compiler takes this:



public class A

private readonly int i;

public A()

void SetI()

i = 10;


SetI();




and turns it into this:



public class A

private readonly int i;

public A()

<.ctor>g__SetI

[CompilerGenerated]
private void <.ctor>g__SetI


(SharpLab. I left off the readonly so it would compile.)



As you can see, it's trying to assign i from the method <.ctor>g__SetI|1_0(), which isn't a constructor.



Unfortunately the C# 7.0 language specification hasn't yet been published, so I can't quote it.



Exactly the same happens if you try and use a delegate:



public class A

private readonly int i;

public A()

Action setI = () => i = 10;

setI();




Gets compiled to:



public class A

private readonly int i;

public A()

Action action = <.ctor>b__1_0;
action();


[CompilerGenerated]
private void <.ctor>b__1_0()

i = 10;




(SharpLab, again with the readonly.)



... which likewise fails to compile.






share|improve this answer

























  • Thanks @canton7, I am looking forward to the c#7/8 language specification when/if it arrives.

    – ilias
    yesterday
















16














The compiler turns the SetI local function into a separate class-level method. Since this separate class-level method is not a constructor, you are not allowed to assign to readonly fields from it.



So the compiler takes this:



public class A

private readonly int i;

public A()

void SetI()

i = 10;


SetI();




and turns it into this:



public class A

private readonly int i;

public A()

<.ctor>g__SetI

[CompilerGenerated]
private void <.ctor>g__SetI


(SharpLab. I left off the readonly so it would compile.)



As you can see, it's trying to assign i from the method <.ctor>g__SetI|1_0(), which isn't a constructor.



Unfortunately the C# 7.0 language specification hasn't yet been published, so I can't quote it.



Exactly the same happens if you try and use a delegate:



public class A

private readonly int i;

public A()

Action setI = () => i = 10;

setI();




Gets compiled to:



public class A

private readonly int i;

public A()

Action action = <.ctor>b__1_0;
action();


[CompilerGenerated]
private void <.ctor>b__1_0()

i = 10;




(SharpLab, again with the readonly.)



... which likewise fails to compile.






share|improve this answer

























  • Thanks @canton7, I am looking forward to the c#7/8 language specification when/if it arrives.

    – ilias
    yesterday














16












16








16







The compiler turns the SetI local function into a separate class-level method. Since this separate class-level method is not a constructor, you are not allowed to assign to readonly fields from it.



So the compiler takes this:



public class A

private readonly int i;

public A()

void SetI()

i = 10;


SetI();




and turns it into this:



public class A

private readonly int i;

public A()

<.ctor>g__SetI

[CompilerGenerated]
private void <.ctor>g__SetI


(SharpLab. I left off the readonly so it would compile.)



As you can see, it's trying to assign i from the method <.ctor>g__SetI|1_0(), which isn't a constructor.



Unfortunately the C# 7.0 language specification hasn't yet been published, so I can't quote it.



Exactly the same happens if you try and use a delegate:



public class A

private readonly int i;

public A()

Action setI = () => i = 10;

setI();




Gets compiled to:



public class A

private readonly int i;

public A()

Action action = <.ctor>b__1_0;
action();


[CompilerGenerated]
private void <.ctor>b__1_0()

i = 10;




(SharpLab, again with the readonly.)



... which likewise fails to compile.






share|improve this answer















The compiler turns the SetI local function into a separate class-level method. Since this separate class-level method is not a constructor, you are not allowed to assign to readonly fields from it.



So the compiler takes this:



public class A

private readonly int i;

public A()

void SetI()

i = 10;


SetI();




and turns it into this:



public class A

private readonly int i;

public A()

<.ctor>g__SetI

[CompilerGenerated]
private void <.ctor>g__SetI


(SharpLab. I left off the readonly so it would compile.)



As you can see, it's trying to assign i from the method <.ctor>g__SetI|1_0(), which isn't a constructor.



Unfortunately the C# 7.0 language specification hasn't yet been published, so I can't quote it.



Exactly the same happens if you try and use a delegate:



public class A

private readonly int i;

public A()

Action setI = () => i = 10;

setI();




Gets compiled to:



public class A

private readonly int i;

public A()

Action action = <.ctor>b__1_0;
action();


[CompilerGenerated]
private void <.ctor>b__1_0()

i = 10;




(SharpLab, again with the readonly.)



... which likewise fails to compile.







share|improve this answer














share|improve this answer



share|improve this answer








edited yesterday

























answered yesterday









canton7canton7

4,3761728




4,3761728












  • Thanks @canton7, I am looking forward to the c#7/8 language specification when/if it arrives.

    – ilias
    yesterday


















  • Thanks @canton7, I am looking forward to the c#7/8 language specification when/if it arrives.

    – ilias
    yesterday

















Thanks @canton7, I am looking forward to the c#7/8 language specification when/if it arrives.

– ilias
yesterday






Thanks @canton7, I am looking forward to the c#7/8 language specification when/if it arrives.

– ilias
yesterday




















draft saved

draft discarded
















































Thanks for contributing an answer to Stack Overflow!


  • Please be sure to answer the question. Provide details and share your research!

But avoid


  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55181639%2fset-readonly-fields-in-a-constructor-local-function-c-sharp%23new-answer', 'question_page');

);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

Adding axes to figuresAdding axes labels to LaTeX figuresLaTeX equivalent of ConTeXt buffersRotate a node but not its content: the case of the ellipse decorationHow to define the default vertical distance between nodes?TikZ scaling graphic and adjust node position and keep font sizeNumerical conditional within tikz keys?adding axes to shapesAlign axes across subfiguresAdding figures with a certain orderLine up nested tikz enviroments or how to get rid of themAdding axes labels to LaTeX figures

Luettelo Yhdysvaltain laivaston lentotukialuksista Lähteet | Navigointivalikko

Gary (muusikko) Sisällysluettelo Historia | Rockin' High | Lähteet | Aiheesta muualla | NavigointivalikkoInfobox OKTuomas "Gary" Keskinen Ancaran kitaristiksiProjekti Rockin' High