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
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
|
show 2 more comments
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
6
The compiler turns theSetI
local function into a separate class-level method. Since this separate class-level method is not a constructor, you are not allowed to assign toreadonly
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 makeSetI
return the desired value instead of assigning it directly, or use anout
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
|
show 2 more comments
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
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
c# constructor compiler-errors readonly local-functions
edited yesterday
Kris Harper
2,99152865
2,99152865
asked yesterday
iliasilias
1,20421729
1,20421729
6
The compiler turns theSetI
local function into a separate class-level method. Since this separate class-level method is not a constructor, you are not allowed to assign toreadonly
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 makeSetI
return the desired value instead of assigning it directly, or use anout
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
|
show 2 more comments
6
The compiler turns theSetI
local function into a separate class-level method. Since this separate class-level method is not a constructor, you are not allowed to assign toreadonly
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 makeSetI
return the desired value instead of assigning it directly, or use anout
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
|
show 2 more comments
1 Answer
1
active
oldest
votes
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.
Thanks @canton7, I am looking forward to the c#7/8 language specification when/if it arrives.
– ilias
yesterday
add a comment |
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
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
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.
Thanks @canton7, I am looking forward to the c#7/8 language specification when/if it arrives.
– ilias
yesterday
add a comment |
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.
Thanks @canton7, I am looking forward to the c#7/8 language specification when/if it arrives.
– ilias
yesterday
add a comment |
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.
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.
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
add a comment |
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
add a comment |
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.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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
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 toreadonly
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 anout
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