Declare a const array
Is it possible to write something similar to the following?
public const string Titles = { "German", "Spanish", "Corrects", "Wrongs" };
c# .net arrays const readonly
add a comment |
Is it possible to write something similar to the following?
public const string Titles = { "German", "Spanish", "Corrects", "Wrongs" };
c# .net arrays const readonly
static could be used, public static string Titles = new string { "German", "Spanish"};
– Ray Fan
May 23 '14 at 18:07
add a comment |
Is it possible to write something similar to the following?
public const string Titles = { "German", "Spanish", "Corrects", "Wrongs" };
c# .net arrays const readonly
Is it possible to write something similar to the following?
public const string Titles = { "German", "Spanish", "Corrects", "Wrongs" };
c# .net arrays const readonly
c# .net arrays const readonly
edited Mar 1 '18 at 20:21
Kirill Kobelev
8,83552244
8,83552244
asked Feb 28 '11 at 13:04
Jaime OroJaime Oro
4,10382536
4,10382536
static could be used, public static string Titles = new string { "German", "Spanish"};
– Ray Fan
May 23 '14 at 18:07
add a comment |
static could be used, public static string Titles = new string { "German", "Spanish"};
– Ray Fan
May 23 '14 at 18:07
static could be used, public static string Titles = new string { "German", "Spanish"};
– Ray Fan
May 23 '14 at 18:07
static could be used, public static string Titles = new string { "German", "Spanish"};
– Ray Fan
May 23 '14 at 18:07
add a comment |
13 Answers
13
active
oldest
votes
Yes, but you need to declare it readonly
instead of const
:
public static readonly string Titles = { "German", "Spanish", "Corrects", "Wrongs" };
The reason is that const
can only be applied to a field whose value is known at compile-time. The array initializer you've shown is not a constant expression in C#, so it produces a compiler error.
Declaring it readonly
solves that problem because the value is not initialized until run-time (although it's guaranteed to have initialized before the first time that the array is used).
Depending on what it is that you ultimately want to achieve, you might also consider declaring an enum:
public enum Titles { German, Spanish, Corrects, Wrongs };
93
Note that the array here isn't readonly, of course; Titles[2]="Welsh"; would work just fine at runtime
– Marc Gravell♦
Feb 28 '11 at 13:08
40
You probably want it static too
– tymtam
Jan 24 '13 at 4:31
4
how about declaring a "const" array in a method body, not in the class one?
– serhio
Jan 7 '14 at 9:07
13
Sorry for the down vote, but const also implies static. Declaring the array as read only is not close to a workaround. it needs to bereadonly static
to have any resemblance of the requested semantics.
– Anton
Dec 7 '14 at 15:47
2
string isn't a char, see the source. Strings can be consts in C# because the compiler will replace all references to the const with the actual string literal itself.
– Niall Connaughton
Sep 23 '15 at 5:22
|
show 5 more comments
You can declare array as readonly
, but keep in mind that you can change element of readonly
array.
public readonly string Titles = { "German", "Spanish", "Corrects", "Wrongs" };
...
Titles[0] = "bla";
Consider using enum, as Cody suggested, or IList.
public readonly IList<string> ITitles = new List<string> {"German", "Spanish", "Corrects", "Wrongs" }.AsReadOnly();
23
In .NET 4.5 and higher you can declare a list as IReadOnlyList<string> instead of IList<string>.
– Grzegorz Smulko
Jul 4 '14 at 9:54
add a comment |
You can't create a 'const' array because arrays are objects and can only be
created at runtime and const entities are resolved at compile time.
What you can do instead is to declare your array as "readonly". This has the
same effect as const except the value can be set at runtime. It can only be
set once and it is thereafter a readonly (i.e. const) value.
add a comment |
Since C# 6 you can write it like:
public static string Titles => new string { "German", "Spanish", "Corrects", "Wrongs" };
See also: C# : The New and Improved C# 6.0 (specifically the chapter "Expression Bodied Functions and Properties")
This will make a read-only static property, but it will still allow you to alter the content of the array returned, but when you call the property again, you will get the original, unaltered array again.
For clarification, this code is the same as (or actually a shorthand for):
public static string Titles
{
get { return new string { "German", "Spanish", "Corrects", "Wrongs" }; }
}
Please note that there is a downside to this approach: A new array is actually instantiated on each and every reference, so if you are using a very large array, this might not be the most efficient solution.
But if you re-use the same array (by putting it in a private attribute for instance) it will again open up the possibility to change the contents of the array.
If you want to have an immutable array (or list) you could also use:
public static IReadOnlyList<string> Titles { get; } = new string { "German", "Spanish", "Corrects", "Wrongs" };
But, this still has a risk for changes, as you can still cast it back to a string and alter the contents, as such:
((string) Titles)[1] = "French";
1
What is the profit of using property instead of field in this case?
– nicolay.anykienko
Oct 12 '16 at 16:28
2
A field cannot return a new object on each call. A property is basically a sort of "function in disguise".
– mjepson
Dec 1 '16 at 10:47
1
If you were referring to the last option, that can be done using both a field or a property, but since it is public, I prefer a Property. I never use a public field since the introduction of Properties.
– mjepson
Dec 1 '16 at 10:48
There is another downside to the 1st approach: you won't get a compilation error if you assign toTitles[0]
, for instance - in effect, the assignment attempt is quietly ignored. Combined with the inefficiency of recreating the array every time, I wonder if this approach is even worth showing. By contrast, the 2nd approach is efficient, and you have to go out of your way to defeat the immutability.
– mklement0
Apr 4 '17 at 14:31
add a comment |
You could take a different approach: define a constant string to represent your array and then split the string into an array when you need it, e.g.
const string DefaultDistances = "5,10,15,20,25,30,40,50";
public static readonly string distances = DefaultDistances.Split(',');
This approach gives you a constant which can be stored in configuration and converted to an array when needed.
Alastair
6
I think the cost of performing the split far outstrips any benefits made by defining const. But +1 for a unique approach and thinking outside the box! ;)
– Radderz
Oct 15 '15 at 16:56
I was about to post the same solution and then saw this, contrary to the harsh and negative remarks, this was actually perfect for my scenario, where i needed to pass a const to an Attribute, and then i split the value in attribute constructor to get what i needed. and i see no reason why it will have performance cost since attributes are not created for each instance.
– Kalpesh Popat
Oct 3 '18 at 4:43
add a comment |
For my needs I define static
array, instead of impossible const
and it works:
public static string Titles = { "German", "Spanish", "Corrects", "Wrongs" };
1
Simply removingconst
from OP example also works, but that (or your answer) allows to change both:Titles
instance and any value. So what is the point in this answer?
– Sinatr
Mar 24 '16 at 13:05
@Sinatr, I answered this 3 years ago, when I strted working in C#. I left it, now I'm in Java world. Perhaps I forgot to addreadonly
– ALZ
Mar 24 '16 at 18:09
After second thought, your answer is a direct how to make OP code working, without anyconst
/readonly
considerations, simply making it working (like ifconst
was a syntax mistake). For some people it seems to be a valuable answer (perhaps they also tried to useconst
by mistake?).
– Sinatr
Mar 29 '16 at 8:11
add a comment |
If you declare an array behind an IReadOnlyList interface you get a constant array with constant values that is declared at runtime:
public readonly IReadOnlyList<string> Titles = new {"German", "Spanish", "Corrects", "Wrongs" };
Available in .NET 4.5 and higher.
add a comment |
This is a way to do what you want:
using System;
using System.Collections.ObjectModel;
using System.Collections.Generic;
public ReadOnlyCollection<string> Titles { get { return new List<string> { "German", "Spanish", "Corrects", "Wrongs" }.AsReadOnly();}}
It is very similar to doing a readonly array.
8
You can just do that aspublic static readonly ReadOnlyCollection<String> Titles = new List<String> { "German", "Spanish", "Corrects", "Wrongs" }.AsReadOnly();
; no need to recreate the list on every retrieve if you make it a ReadOnlyCollection anyway.
– Nyerguds
Sep 21 '15 at 8:48
add a comment |
I believe you can only make it readonly.
add a comment |
A .NET Framework v4.5+ solution that improves on tdbeckett's answer:
using System.Collections.ObjectModel;
// ...
public ReadOnlyCollection<string> Titles { get; } = new ReadOnlyCollection<string>(
new string { "German", "Spanish", "Corrects", "Wrongs" }
);
Note: Given that the collection is conceptually constant, it may make sense to make it static
to declare it at the class level.
The above:
Initializes the property's implicit backing field once with the array.
Note that
{ get; }
- i.e., declaring only a property getter - is what makes the property itself implicitly read-only (trying to combinereadonly
with{ get; }
is actually a syntax error).Alternatively, you could just omit the
{ get; }
and addreadonly
to create a field instead of a property, as in the question, but exposing public data members as properties rather than fields is a good habit to form.
Creates an array-like structure (allowing indexed access) that is truly and robustly read-only (conceptually constant, once created), both with respect to:
preventing modification of the collection as a whole (such as by removing or adding elements, or by assigning a new collection to the variable).
preventing modification of individual elements.
(Even indirect modification isn't possible - unlike with anIReadOnlyList<T>
solution, where a(string)
cast can be used to gain write access to the elements, as shown in mjepsen's helpful answer.
The same vulnerability applies to theIReadOnlyCollection<T>
interface, which, despite the similarity in name to classReadOnlyCollection
, does not even support indexed access, making it fundamentally unsuitable for providing array-like access.)
1
@mortb: Unfortunately,IReadOnlyCollection
doesn't support indexed access, so it can't be used here. Additionally, likeIReadOnlyList
(which does have indexed access) it is susceptible to element manipulation by casting back tostring
. In other words:ReadOnlyCollection
(which you cannot cast a string array to) is the most robust solution. Not using a getter is an option (and I've updated the answer to note that), but with public data it's probably better to stick with a property.
– mklement0
Apr 6 '17 at 12:07
add a comment |
Arrays are probably one of those things that can only be evaluated at
runtime. Constants must be evaluated at compile time. Try using "readonly"
instead of "const".
add a comment |
For the sake of completeness, now we also have ImmutableArrays at our disposal.
This should be truly immutable:
public readonly static ImmutableArray<string> Tiles = ImmutableArray.Create(new { "German", "Spanish", "Corrects", "Wrongs" });
Requires System.Collections.Immutable NuGet reference
https://msdn.microsoft.com/en-us/library/mt452182(v=vs.111).aspx
add a comment |
As an alternative, to get around the elements-can-be-modified issue with a readonly array, you can use a static property instead. (The individual elements can still be changed, but these changes will only be made on the local copy of the array.)
public static string Titles
{
get
{
return new string { "German", "Spanish", "Corrects", "Wrongs"};
}
}
Of course, this will not be particularly efficient as a new string array is created each time.
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%2f5142349%2fdeclare-a-const-array%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
13 Answers
13
active
oldest
votes
13 Answers
13
active
oldest
votes
active
oldest
votes
active
oldest
votes
Yes, but you need to declare it readonly
instead of const
:
public static readonly string Titles = { "German", "Spanish", "Corrects", "Wrongs" };
The reason is that const
can only be applied to a field whose value is known at compile-time. The array initializer you've shown is not a constant expression in C#, so it produces a compiler error.
Declaring it readonly
solves that problem because the value is not initialized until run-time (although it's guaranteed to have initialized before the first time that the array is used).
Depending on what it is that you ultimately want to achieve, you might also consider declaring an enum:
public enum Titles { German, Spanish, Corrects, Wrongs };
93
Note that the array here isn't readonly, of course; Titles[2]="Welsh"; would work just fine at runtime
– Marc Gravell♦
Feb 28 '11 at 13:08
40
You probably want it static too
– tymtam
Jan 24 '13 at 4:31
4
how about declaring a "const" array in a method body, not in the class one?
– serhio
Jan 7 '14 at 9:07
13
Sorry for the down vote, but const also implies static. Declaring the array as read only is not close to a workaround. it needs to bereadonly static
to have any resemblance of the requested semantics.
– Anton
Dec 7 '14 at 15:47
2
string isn't a char, see the source. Strings can be consts in C# because the compiler will replace all references to the const with the actual string literal itself.
– Niall Connaughton
Sep 23 '15 at 5:22
|
show 5 more comments
Yes, but you need to declare it readonly
instead of const
:
public static readonly string Titles = { "German", "Spanish", "Corrects", "Wrongs" };
The reason is that const
can only be applied to a field whose value is known at compile-time. The array initializer you've shown is not a constant expression in C#, so it produces a compiler error.
Declaring it readonly
solves that problem because the value is not initialized until run-time (although it's guaranteed to have initialized before the first time that the array is used).
Depending on what it is that you ultimately want to achieve, you might also consider declaring an enum:
public enum Titles { German, Spanish, Corrects, Wrongs };
93
Note that the array here isn't readonly, of course; Titles[2]="Welsh"; would work just fine at runtime
– Marc Gravell♦
Feb 28 '11 at 13:08
40
You probably want it static too
– tymtam
Jan 24 '13 at 4:31
4
how about declaring a "const" array in a method body, not in the class one?
– serhio
Jan 7 '14 at 9:07
13
Sorry for the down vote, but const also implies static. Declaring the array as read only is not close to a workaround. it needs to bereadonly static
to have any resemblance of the requested semantics.
– Anton
Dec 7 '14 at 15:47
2
string isn't a char, see the source. Strings can be consts in C# because the compiler will replace all references to the const with the actual string literal itself.
– Niall Connaughton
Sep 23 '15 at 5:22
|
show 5 more comments
Yes, but you need to declare it readonly
instead of const
:
public static readonly string Titles = { "German", "Spanish", "Corrects", "Wrongs" };
The reason is that const
can only be applied to a field whose value is known at compile-time. The array initializer you've shown is not a constant expression in C#, so it produces a compiler error.
Declaring it readonly
solves that problem because the value is not initialized until run-time (although it's guaranteed to have initialized before the first time that the array is used).
Depending on what it is that you ultimately want to achieve, you might also consider declaring an enum:
public enum Titles { German, Spanish, Corrects, Wrongs };
Yes, but you need to declare it readonly
instead of const
:
public static readonly string Titles = { "German", "Spanish", "Corrects", "Wrongs" };
The reason is that const
can only be applied to a field whose value is known at compile-time. The array initializer you've shown is not a constant expression in C#, so it produces a compiler error.
Declaring it readonly
solves that problem because the value is not initialized until run-time (although it's guaranteed to have initialized before the first time that the array is used).
Depending on what it is that you ultimately want to achieve, you might also consider declaring an enum:
public enum Titles { German, Spanish, Corrects, Wrongs };
edited Mar 11 '16 at 13:34
answered Feb 28 '11 at 13:07
Cody Gray♦Cody Gray
194k35379467
194k35379467
93
Note that the array here isn't readonly, of course; Titles[2]="Welsh"; would work just fine at runtime
– Marc Gravell♦
Feb 28 '11 at 13:08
40
You probably want it static too
– tymtam
Jan 24 '13 at 4:31
4
how about declaring a "const" array in a method body, not in the class one?
– serhio
Jan 7 '14 at 9:07
13
Sorry for the down vote, but const also implies static. Declaring the array as read only is not close to a workaround. it needs to bereadonly static
to have any resemblance of the requested semantics.
– Anton
Dec 7 '14 at 15:47
2
string isn't a char, see the source. Strings can be consts in C# because the compiler will replace all references to the const with the actual string literal itself.
– Niall Connaughton
Sep 23 '15 at 5:22
|
show 5 more comments
93
Note that the array here isn't readonly, of course; Titles[2]="Welsh"; would work just fine at runtime
– Marc Gravell♦
Feb 28 '11 at 13:08
40
You probably want it static too
– tymtam
Jan 24 '13 at 4:31
4
how about declaring a "const" array in a method body, not in the class one?
– serhio
Jan 7 '14 at 9:07
13
Sorry for the down vote, but const also implies static. Declaring the array as read only is not close to a workaround. it needs to bereadonly static
to have any resemblance of the requested semantics.
– Anton
Dec 7 '14 at 15:47
2
string isn't a char, see the source. Strings can be consts in C# because the compiler will replace all references to the const with the actual string literal itself.
– Niall Connaughton
Sep 23 '15 at 5:22
93
93
Note that the array here isn't readonly, of course; Titles[2]="Welsh"; would work just fine at runtime
– Marc Gravell♦
Feb 28 '11 at 13:08
Note that the array here isn't readonly, of course; Titles[2]="Welsh"; would work just fine at runtime
– Marc Gravell♦
Feb 28 '11 at 13:08
40
40
You probably want it static too
– tymtam
Jan 24 '13 at 4:31
You probably want it static too
– tymtam
Jan 24 '13 at 4:31
4
4
how about declaring a "const" array in a method body, not in the class one?
– serhio
Jan 7 '14 at 9:07
how about declaring a "const" array in a method body, not in the class one?
– serhio
Jan 7 '14 at 9:07
13
13
Sorry for the down vote, but const also implies static. Declaring the array as read only is not close to a workaround. it needs to be
readonly static
to have any resemblance of the requested semantics.– Anton
Dec 7 '14 at 15:47
Sorry for the down vote, but const also implies static. Declaring the array as read only is not close to a workaround. it needs to be
readonly static
to have any resemblance of the requested semantics.– Anton
Dec 7 '14 at 15:47
2
2
string isn't a char, see the source. Strings can be consts in C# because the compiler will replace all references to the const with the actual string literal itself.
– Niall Connaughton
Sep 23 '15 at 5:22
string isn't a char, see the source. Strings can be consts in C# because the compiler will replace all references to the const with the actual string literal itself.
– Niall Connaughton
Sep 23 '15 at 5:22
|
show 5 more comments
You can declare array as readonly
, but keep in mind that you can change element of readonly
array.
public readonly string Titles = { "German", "Spanish", "Corrects", "Wrongs" };
...
Titles[0] = "bla";
Consider using enum, as Cody suggested, or IList.
public readonly IList<string> ITitles = new List<string> {"German", "Spanish", "Corrects", "Wrongs" }.AsReadOnly();
23
In .NET 4.5 and higher you can declare a list as IReadOnlyList<string> instead of IList<string>.
– Grzegorz Smulko
Jul 4 '14 at 9:54
add a comment |
You can declare array as readonly
, but keep in mind that you can change element of readonly
array.
public readonly string Titles = { "German", "Spanish", "Corrects", "Wrongs" };
...
Titles[0] = "bla";
Consider using enum, as Cody suggested, or IList.
public readonly IList<string> ITitles = new List<string> {"German", "Spanish", "Corrects", "Wrongs" }.AsReadOnly();
23
In .NET 4.5 and higher you can declare a list as IReadOnlyList<string> instead of IList<string>.
– Grzegorz Smulko
Jul 4 '14 at 9:54
add a comment |
You can declare array as readonly
, but keep in mind that you can change element of readonly
array.
public readonly string Titles = { "German", "Spanish", "Corrects", "Wrongs" };
...
Titles[0] = "bla";
Consider using enum, as Cody suggested, or IList.
public readonly IList<string> ITitles = new List<string> {"German", "Spanish", "Corrects", "Wrongs" }.AsReadOnly();
You can declare array as readonly
, but keep in mind that you can change element of readonly
array.
public readonly string Titles = { "German", "Spanish", "Corrects", "Wrongs" };
...
Titles[0] = "bla";
Consider using enum, as Cody suggested, or IList.
public readonly IList<string> ITitles = new List<string> {"German", "Spanish", "Corrects", "Wrongs" }.AsReadOnly();
edited Feb 28 '11 at 13:33
answered Feb 28 '11 at 13:23
BranimirBranimir
3,4051629
3,4051629
23
In .NET 4.5 and higher you can declare a list as IReadOnlyList<string> instead of IList<string>.
– Grzegorz Smulko
Jul 4 '14 at 9:54
add a comment |
23
In .NET 4.5 and higher you can declare a list as IReadOnlyList<string> instead of IList<string>.
– Grzegorz Smulko
Jul 4 '14 at 9:54
23
23
In .NET 4.5 and higher you can declare a list as IReadOnlyList<string> instead of IList<string>.
– Grzegorz Smulko
Jul 4 '14 at 9:54
In .NET 4.5 and higher you can declare a list as IReadOnlyList<string> instead of IList<string>.
– Grzegorz Smulko
Jul 4 '14 at 9:54
add a comment |
You can't create a 'const' array because arrays are objects and can only be
created at runtime and const entities are resolved at compile time.
What you can do instead is to declare your array as "readonly". This has the
same effect as const except the value can be set at runtime. It can only be
set once and it is thereafter a readonly (i.e. const) value.
add a comment |
You can't create a 'const' array because arrays are objects and can only be
created at runtime and const entities are resolved at compile time.
What you can do instead is to declare your array as "readonly". This has the
same effect as const except the value can be set at runtime. It can only be
set once and it is thereafter a readonly (i.e. const) value.
add a comment |
You can't create a 'const' array because arrays are objects and can only be
created at runtime and const entities are resolved at compile time.
What you can do instead is to declare your array as "readonly". This has the
same effect as const except the value can be set at runtime. It can only be
set once and it is thereafter a readonly (i.e. const) value.
You can't create a 'const' array because arrays are objects and can only be
created at runtime and const entities are resolved at compile time.
What you can do instead is to declare your array as "readonly". This has the
same effect as const except the value can be set at runtime. It can only be
set once and it is thereafter a readonly (i.e. const) value.
answered Feb 28 '11 at 13:08
JAiroJAiro
4,53821720
4,53821720
add a comment |
add a comment |
Since C# 6 you can write it like:
public static string Titles => new string { "German", "Spanish", "Corrects", "Wrongs" };
See also: C# : The New and Improved C# 6.0 (specifically the chapter "Expression Bodied Functions and Properties")
This will make a read-only static property, but it will still allow you to alter the content of the array returned, but when you call the property again, you will get the original, unaltered array again.
For clarification, this code is the same as (or actually a shorthand for):
public static string Titles
{
get { return new string { "German", "Spanish", "Corrects", "Wrongs" }; }
}
Please note that there is a downside to this approach: A new array is actually instantiated on each and every reference, so if you are using a very large array, this might not be the most efficient solution.
But if you re-use the same array (by putting it in a private attribute for instance) it will again open up the possibility to change the contents of the array.
If you want to have an immutable array (or list) you could also use:
public static IReadOnlyList<string> Titles { get; } = new string { "German", "Spanish", "Corrects", "Wrongs" };
But, this still has a risk for changes, as you can still cast it back to a string and alter the contents, as such:
((string) Titles)[1] = "French";
1
What is the profit of using property instead of field in this case?
– nicolay.anykienko
Oct 12 '16 at 16:28
2
A field cannot return a new object on each call. A property is basically a sort of "function in disguise".
– mjepson
Dec 1 '16 at 10:47
1
If you were referring to the last option, that can be done using both a field or a property, but since it is public, I prefer a Property. I never use a public field since the introduction of Properties.
– mjepson
Dec 1 '16 at 10:48
There is another downside to the 1st approach: you won't get a compilation error if you assign toTitles[0]
, for instance - in effect, the assignment attempt is quietly ignored. Combined with the inefficiency of recreating the array every time, I wonder if this approach is even worth showing. By contrast, the 2nd approach is efficient, and you have to go out of your way to defeat the immutability.
– mklement0
Apr 4 '17 at 14:31
add a comment |
Since C# 6 you can write it like:
public static string Titles => new string { "German", "Spanish", "Corrects", "Wrongs" };
See also: C# : The New and Improved C# 6.0 (specifically the chapter "Expression Bodied Functions and Properties")
This will make a read-only static property, but it will still allow you to alter the content of the array returned, but when you call the property again, you will get the original, unaltered array again.
For clarification, this code is the same as (or actually a shorthand for):
public static string Titles
{
get { return new string { "German", "Spanish", "Corrects", "Wrongs" }; }
}
Please note that there is a downside to this approach: A new array is actually instantiated on each and every reference, so if you are using a very large array, this might not be the most efficient solution.
But if you re-use the same array (by putting it in a private attribute for instance) it will again open up the possibility to change the contents of the array.
If you want to have an immutable array (or list) you could also use:
public static IReadOnlyList<string> Titles { get; } = new string { "German", "Spanish", "Corrects", "Wrongs" };
But, this still has a risk for changes, as you can still cast it back to a string and alter the contents, as such:
((string) Titles)[1] = "French";
1
What is the profit of using property instead of field in this case?
– nicolay.anykienko
Oct 12 '16 at 16:28
2
A field cannot return a new object on each call. A property is basically a sort of "function in disguise".
– mjepson
Dec 1 '16 at 10:47
1
If you were referring to the last option, that can be done using both a field or a property, but since it is public, I prefer a Property. I never use a public field since the introduction of Properties.
– mjepson
Dec 1 '16 at 10:48
There is another downside to the 1st approach: you won't get a compilation error if you assign toTitles[0]
, for instance - in effect, the assignment attempt is quietly ignored. Combined with the inefficiency of recreating the array every time, I wonder if this approach is even worth showing. By contrast, the 2nd approach is efficient, and you have to go out of your way to defeat the immutability.
– mklement0
Apr 4 '17 at 14:31
add a comment |
Since C# 6 you can write it like:
public static string Titles => new string { "German", "Spanish", "Corrects", "Wrongs" };
See also: C# : The New and Improved C# 6.0 (specifically the chapter "Expression Bodied Functions and Properties")
This will make a read-only static property, but it will still allow you to alter the content of the array returned, but when you call the property again, you will get the original, unaltered array again.
For clarification, this code is the same as (or actually a shorthand for):
public static string Titles
{
get { return new string { "German", "Spanish", "Corrects", "Wrongs" }; }
}
Please note that there is a downside to this approach: A new array is actually instantiated on each and every reference, so if you are using a very large array, this might not be the most efficient solution.
But if you re-use the same array (by putting it in a private attribute for instance) it will again open up the possibility to change the contents of the array.
If you want to have an immutable array (or list) you could also use:
public static IReadOnlyList<string> Titles { get; } = new string { "German", "Spanish", "Corrects", "Wrongs" };
But, this still has a risk for changes, as you can still cast it back to a string and alter the contents, as such:
((string) Titles)[1] = "French";
Since C# 6 you can write it like:
public static string Titles => new string { "German", "Spanish", "Corrects", "Wrongs" };
See also: C# : The New and Improved C# 6.0 (specifically the chapter "Expression Bodied Functions and Properties")
This will make a read-only static property, but it will still allow you to alter the content of the array returned, but when you call the property again, you will get the original, unaltered array again.
For clarification, this code is the same as (or actually a shorthand for):
public static string Titles
{
get { return new string { "German", "Spanish", "Corrects", "Wrongs" }; }
}
Please note that there is a downside to this approach: A new array is actually instantiated on each and every reference, so if you are using a very large array, this might not be the most efficient solution.
But if you re-use the same array (by putting it in a private attribute for instance) it will again open up the possibility to change the contents of the array.
If you want to have an immutable array (or list) you could also use:
public static IReadOnlyList<string> Titles { get; } = new string { "German", "Spanish", "Corrects", "Wrongs" };
But, this still has a risk for changes, as you can still cast it back to a string and alter the contents, as such:
((string) Titles)[1] = "French";
edited Aug 9 '16 at 14:37
answered Aug 9 '16 at 6:54
mjepsonmjepson
320314
320314
1
What is the profit of using property instead of field in this case?
– nicolay.anykienko
Oct 12 '16 at 16:28
2
A field cannot return a new object on each call. A property is basically a sort of "function in disguise".
– mjepson
Dec 1 '16 at 10:47
1
If you were referring to the last option, that can be done using both a field or a property, but since it is public, I prefer a Property. I never use a public field since the introduction of Properties.
– mjepson
Dec 1 '16 at 10:48
There is another downside to the 1st approach: you won't get a compilation error if you assign toTitles[0]
, for instance - in effect, the assignment attempt is quietly ignored. Combined with the inefficiency of recreating the array every time, I wonder if this approach is even worth showing. By contrast, the 2nd approach is efficient, and you have to go out of your way to defeat the immutability.
– mklement0
Apr 4 '17 at 14:31
add a comment |
1
What is the profit of using property instead of field in this case?
– nicolay.anykienko
Oct 12 '16 at 16:28
2
A field cannot return a new object on each call. A property is basically a sort of "function in disguise".
– mjepson
Dec 1 '16 at 10:47
1
If you were referring to the last option, that can be done using both a field or a property, but since it is public, I prefer a Property. I never use a public field since the introduction of Properties.
– mjepson
Dec 1 '16 at 10:48
There is another downside to the 1st approach: you won't get a compilation error if you assign toTitles[0]
, for instance - in effect, the assignment attempt is quietly ignored. Combined with the inefficiency of recreating the array every time, I wonder if this approach is even worth showing. By contrast, the 2nd approach is efficient, and you have to go out of your way to defeat the immutability.
– mklement0
Apr 4 '17 at 14:31
1
1
What is the profit of using property instead of field in this case?
– nicolay.anykienko
Oct 12 '16 at 16:28
What is the profit of using property instead of field in this case?
– nicolay.anykienko
Oct 12 '16 at 16:28
2
2
A field cannot return a new object on each call. A property is basically a sort of "function in disguise".
– mjepson
Dec 1 '16 at 10:47
A field cannot return a new object on each call. A property is basically a sort of "function in disguise".
– mjepson
Dec 1 '16 at 10:47
1
1
If you were referring to the last option, that can be done using both a field or a property, but since it is public, I prefer a Property. I never use a public field since the introduction of Properties.
– mjepson
Dec 1 '16 at 10:48
If you were referring to the last option, that can be done using both a field or a property, but since it is public, I prefer a Property. I never use a public field since the introduction of Properties.
– mjepson
Dec 1 '16 at 10:48
There is another downside to the 1st approach: you won't get a compilation error if you assign to
Titles[0]
, for instance - in effect, the assignment attempt is quietly ignored. Combined with the inefficiency of recreating the array every time, I wonder if this approach is even worth showing. By contrast, the 2nd approach is efficient, and you have to go out of your way to defeat the immutability.– mklement0
Apr 4 '17 at 14:31
There is another downside to the 1st approach: you won't get a compilation error if you assign to
Titles[0]
, for instance - in effect, the assignment attempt is quietly ignored. Combined with the inefficiency of recreating the array every time, I wonder if this approach is even worth showing. By contrast, the 2nd approach is efficient, and you have to go out of your way to defeat the immutability.– mklement0
Apr 4 '17 at 14:31
add a comment |
You could take a different approach: define a constant string to represent your array and then split the string into an array when you need it, e.g.
const string DefaultDistances = "5,10,15,20,25,30,40,50";
public static readonly string distances = DefaultDistances.Split(',');
This approach gives you a constant which can be stored in configuration and converted to an array when needed.
Alastair
6
I think the cost of performing the split far outstrips any benefits made by defining const. But +1 for a unique approach and thinking outside the box! ;)
– Radderz
Oct 15 '15 at 16:56
I was about to post the same solution and then saw this, contrary to the harsh and negative remarks, this was actually perfect for my scenario, where i needed to pass a const to an Attribute, and then i split the value in attribute constructor to get what i needed. and i see no reason why it will have performance cost since attributes are not created for each instance.
– Kalpesh Popat
Oct 3 '18 at 4:43
add a comment |
You could take a different approach: define a constant string to represent your array and then split the string into an array when you need it, e.g.
const string DefaultDistances = "5,10,15,20,25,30,40,50";
public static readonly string distances = DefaultDistances.Split(',');
This approach gives you a constant which can be stored in configuration and converted to an array when needed.
Alastair
6
I think the cost of performing the split far outstrips any benefits made by defining const. But +1 for a unique approach and thinking outside the box! ;)
– Radderz
Oct 15 '15 at 16:56
I was about to post the same solution and then saw this, contrary to the harsh and negative remarks, this was actually perfect for my scenario, where i needed to pass a const to an Attribute, and then i split the value in attribute constructor to get what i needed. and i see no reason why it will have performance cost since attributes are not created for each instance.
– Kalpesh Popat
Oct 3 '18 at 4:43
add a comment |
You could take a different approach: define a constant string to represent your array and then split the string into an array when you need it, e.g.
const string DefaultDistances = "5,10,15,20,25,30,40,50";
public static readonly string distances = DefaultDistances.Split(',');
This approach gives you a constant which can be stored in configuration and converted to an array when needed.
Alastair
You could take a different approach: define a constant string to represent your array and then split the string into an array when you need it, e.g.
const string DefaultDistances = "5,10,15,20,25,30,40,50";
public static readonly string distances = DefaultDistances.Split(',');
This approach gives you a constant which can be stored in configuration and converted to an array when needed.
Alastair
answered Sep 26 '13 at 10:54
AlastairAlastair
333210
333210
6
I think the cost of performing the split far outstrips any benefits made by defining const. But +1 for a unique approach and thinking outside the box! ;)
– Radderz
Oct 15 '15 at 16:56
I was about to post the same solution and then saw this, contrary to the harsh and negative remarks, this was actually perfect for my scenario, where i needed to pass a const to an Attribute, and then i split the value in attribute constructor to get what i needed. and i see no reason why it will have performance cost since attributes are not created for each instance.
– Kalpesh Popat
Oct 3 '18 at 4:43
add a comment |
6
I think the cost of performing the split far outstrips any benefits made by defining const. But +1 for a unique approach and thinking outside the box! ;)
– Radderz
Oct 15 '15 at 16:56
I was about to post the same solution and then saw this, contrary to the harsh and negative remarks, this was actually perfect for my scenario, where i needed to pass a const to an Attribute, and then i split the value in attribute constructor to get what i needed. and i see no reason why it will have performance cost since attributes are not created for each instance.
– Kalpesh Popat
Oct 3 '18 at 4:43
6
6
I think the cost of performing the split far outstrips any benefits made by defining const. But +1 for a unique approach and thinking outside the box! ;)
– Radderz
Oct 15 '15 at 16:56
I think the cost of performing the split far outstrips any benefits made by defining const. But +1 for a unique approach and thinking outside the box! ;)
– Radderz
Oct 15 '15 at 16:56
I was about to post the same solution and then saw this, contrary to the harsh and negative remarks, this was actually perfect for my scenario, where i needed to pass a const to an Attribute, and then i split the value in attribute constructor to get what i needed. and i see no reason why it will have performance cost since attributes are not created for each instance.
– Kalpesh Popat
Oct 3 '18 at 4:43
I was about to post the same solution and then saw this, contrary to the harsh and negative remarks, this was actually perfect for my scenario, where i needed to pass a const to an Attribute, and then i split the value in attribute constructor to get what i needed. and i see no reason why it will have performance cost since attributes are not created for each instance.
– Kalpesh Popat
Oct 3 '18 at 4:43
add a comment |
For my needs I define static
array, instead of impossible const
and it works:
public static string Titles = { "German", "Spanish", "Corrects", "Wrongs" };
1
Simply removingconst
from OP example also works, but that (or your answer) allows to change both:Titles
instance and any value. So what is the point in this answer?
– Sinatr
Mar 24 '16 at 13:05
@Sinatr, I answered this 3 years ago, when I strted working in C#. I left it, now I'm in Java world. Perhaps I forgot to addreadonly
– ALZ
Mar 24 '16 at 18:09
After second thought, your answer is a direct how to make OP code working, without anyconst
/readonly
considerations, simply making it working (like ifconst
was a syntax mistake). For some people it seems to be a valuable answer (perhaps they also tried to useconst
by mistake?).
– Sinatr
Mar 29 '16 at 8:11
add a comment |
For my needs I define static
array, instead of impossible const
and it works:
public static string Titles = { "German", "Spanish", "Corrects", "Wrongs" };
1
Simply removingconst
from OP example also works, but that (or your answer) allows to change both:Titles
instance and any value. So what is the point in this answer?
– Sinatr
Mar 24 '16 at 13:05
@Sinatr, I answered this 3 years ago, when I strted working in C#. I left it, now I'm in Java world. Perhaps I forgot to addreadonly
– ALZ
Mar 24 '16 at 18:09
After second thought, your answer is a direct how to make OP code working, without anyconst
/readonly
considerations, simply making it working (like ifconst
was a syntax mistake). For some people it seems to be a valuable answer (perhaps they also tried to useconst
by mistake?).
– Sinatr
Mar 29 '16 at 8:11
add a comment |
For my needs I define static
array, instead of impossible const
and it works:
public static string Titles = { "German", "Spanish", "Corrects", "Wrongs" };
For my needs I define static
array, instead of impossible const
and it works:
public static string Titles = { "German", "Spanish", "Corrects", "Wrongs" };
answered Apr 24 '13 at 14:12
ALZALZ
1,13321538
1,13321538
1
Simply removingconst
from OP example also works, but that (or your answer) allows to change both:Titles
instance and any value. So what is the point in this answer?
– Sinatr
Mar 24 '16 at 13:05
@Sinatr, I answered this 3 years ago, when I strted working in C#. I left it, now I'm in Java world. Perhaps I forgot to addreadonly
– ALZ
Mar 24 '16 at 18:09
After second thought, your answer is a direct how to make OP code working, without anyconst
/readonly
considerations, simply making it working (like ifconst
was a syntax mistake). For some people it seems to be a valuable answer (perhaps they also tried to useconst
by mistake?).
– Sinatr
Mar 29 '16 at 8:11
add a comment |
1
Simply removingconst
from OP example also works, but that (or your answer) allows to change both:Titles
instance and any value. So what is the point in this answer?
– Sinatr
Mar 24 '16 at 13:05
@Sinatr, I answered this 3 years ago, when I strted working in C#. I left it, now I'm in Java world. Perhaps I forgot to addreadonly
– ALZ
Mar 24 '16 at 18:09
After second thought, your answer is a direct how to make OP code working, without anyconst
/readonly
considerations, simply making it working (like ifconst
was a syntax mistake). For some people it seems to be a valuable answer (perhaps they also tried to useconst
by mistake?).
– Sinatr
Mar 29 '16 at 8:11
1
1
Simply removing
const
from OP example also works, but that (or your answer) allows to change both: Titles
instance and any value. So what is the point in this answer?– Sinatr
Mar 24 '16 at 13:05
Simply removing
const
from OP example also works, but that (or your answer) allows to change both: Titles
instance and any value. So what is the point in this answer?– Sinatr
Mar 24 '16 at 13:05
@Sinatr, I answered this 3 years ago, when I strted working in C#. I left it, now I'm in Java world. Perhaps I forgot to add
readonly
– ALZ
Mar 24 '16 at 18:09
@Sinatr, I answered this 3 years ago, when I strted working in C#. I left it, now I'm in Java world. Perhaps I forgot to add
readonly
– ALZ
Mar 24 '16 at 18:09
After second thought, your answer is a direct how to make OP code working, without any
const
/readonly
considerations, simply making it working (like if const
was a syntax mistake). For some people it seems to be a valuable answer (perhaps they also tried to use const
by mistake?).– Sinatr
Mar 29 '16 at 8:11
After second thought, your answer is a direct how to make OP code working, without any
const
/readonly
considerations, simply making it working (like if const
was a syntax mistake). For some people it seems to be a valuable answer (perhaps they also tried to use const
by mistake?).– Sinatr
Mar 29 '16 at 8:11
add a comment |
If you declare an array behind an IReadOnlyList interface you get a constant array with constant values that is declared at runtime:
public readonly IReadOnlyList<string> Titles = new {"German", "Spanish", "Corrects", "Wrongs" };
Available in .NET 4.5 and higher.
add a comment |
If you declare an array behind an IReadOnlyList interface you get a constant array with constant values that is declared at runtime:
public readonly IReadOnlyList<string> Titles = new {"German", "Spanish", "Corrects", "Wrongs" };
Available in .NET 4.5 and higher.
add a comment |
If you declare an array behind an IReadOnlyList interface you get a constant array with constant values that is declared at runtime:
public readonly IReadOnlyList<string> Titles = new {"German", "Spanish", "Corrects", "Wrongs" };
Available in .NET 4.5 and higher.
If you declare an array behind an IReadOnlyList interface you get a constant array with constant values that is declared at runtime:
public readonly IReadOnlyList<string> Titles = new {"German", "Spanish", "Corrects", "Wrongs" };
Available in .NET 4.5 and higher.
answered Oct 17 '17 at 9:32
Richard GarsideRichard Garside
40.8k86475
40.8k86475
add a comment |
add a comment |
This is a way to do what you want:
using System;
using System.Collections.ObjectModel;
using System.Collections.Generic;
public ReadOnlyCollection<string> Titles { get { return new List<string> { "German", "Spanish", "Corrects", "Wrongs" }.AsReadOnly();}}
It is very similar to doing a readonly array.
8
You can just do that aspublic static readonly ReadOnlyCollection<String> Titles = new List<String> { "German", "Spanish", "Corrects", "Wrongs" }.AsReadOnly();
; no need to recreate the list on every retrieve if you make it a ReadOnlyCollection anyway.
– Nyerguds
Sep 21 '15 at 8:48
add a comment |
This is a way to do what you want:
using System;
using System.Collections.ObjectModel;
using System.Collections.Generic;
public ReadOnlyCollection<string> Titles { get { return new List<string> { "German", "Spanish", "Corrects", "Wrongs" }.AsReadOnly();}}
It is very similar to doing a readonly array.
8
You can just do that aspublic static readonly ReadOnlyCollection<String> Titles = new List<String> { "German", "Spanish", "Corrects", "Wrongs" }.AsReadOnly();
; no need to recreate the list on every retrieve if you make it a ReadOnlyCollection anyway.
– Nyerguds
Sep 21 '15 at 8:48
add a comment |
This is a way to do what you want:
using System;
using System.Collections.ObjectModel;
using System.Collections.Generic;
public ReadOnlyCollection<string> Titles { get { return new List<string> { "German", "Spanish", "Corrects", "Wrongs" }.AsReadOnly();}}
It is very similar to doing a readonly array.
This is a way to do what you want:
using System;
using System.Collections.ObjectModel;
using System.Collections.Generic;
public ReadOnlyCollection<string> Titles { get { return new List<string> { "German", "Spanish", "Corrects", "Wrongs" }.AsReadOnly();}}
It is very similar to doing a readonly array.
edited May 7 '17 at 13:36
Peter Mortensen
13.7k1986112
13.7k1986112
answered Aug 8 '14 at 20:20
tdbecketttdbeckett
470618
470618
8
You can just do that aspublic static readonly ReadOnlyCollection<String> Titles = new List<String> { "German", "Spanish", "Corrects", "Wrongs" }.AsReadOnly();
; no need to recreate the list on every retrieve if you make it a ReadOnlyCollection anyway.
– Nyerguds
Sep 21 '15 at 8:48
add a comment |
8
You can just do that aspublic static readonly ReadOnlyCollection<String> Titles = new List<String> { "German", "Spanish", "Corrects", "Wrongs" }.AsReadOnly();
; no need to recreate the list on every retrieve if you make it a ReadOnlyCollection anyway.
– Nyerguds
Sep 21 '15 at 8:48
8
8
You can just do that as
public static readonly ReadOnlyCollection<String> Titles = new List<String> { "German", "Spanish", "Corrects", "Wrongs" }.AsReadOnly();
; no need to recreate the list on every retrieve if you make it a ReadOnlyCollection anyway.– Nyerguds
Sep 21 '15 at 8:48
You can just do that as
public static readonly ReadOnlyCollection<String> Titles = new List<String> { "German", "Spanish", "Corrects", "Wrongs" }.AsReadOnly();
; no need to recreate the list on every retrieve if you make it a ReadOnlyCollection anyway.– Nyerguds
Sep 21 '15 at 8:48
add a comment |
I believe you can only make it readonly.
add a comment |
I believe you can only make it readonly.
add a comment |
I believe you can only make it readonly.
I believe you can only make it readonly.
answered Feb 28 '11 at 13:06
skazskaz
10.4k165790
10.4k165790
add a comment |
add a comment |
A .NET Framework v4.5+ solution that improves on tdbeckett's answer:
using System.Collections.ObjectModel;
// ...
public ReadOnlyCollection<string> Titles { get; } = new ReadOnlyCollection<string>(
new string { "German", "Spanish", "Corrects", "Wrongs" }
);
Note: Given that the collection is conceptually constant, it may make sense to make it static
to declare it at the class level.
The above:
Initializes the property's implicit backing field once with the array.
Note that
{ get; }
- i.e., declaring only a property getter - is what makes the property itself implicitly read-only (trying to combinereadonly
with{ get; }
is actually a syntax error).Alternatively, you could just omit the
{ get; }
and addreadonly
to create a field instead of a property, as in the question, but exposing public data members as properties rather than fields is a good habit to form.
Creates an array-like structure (allowing indexed access) that is truly and robustly read-only (conceptually constant, once created), both with respect to:
preventing modification of the collection as a whole (such as by removing or adding elements, or by assigning a new collection to the variable).
preventing modification of individual elements.
(Even indirect modification isn't possible - unlike with anIReadOnlyList<T>
solution, where a(string)
cast can be used to gain write access to the elements, as shown in mjepsen's helpful answer.
The same vulnerability applies to theIReadOnlyCollection<T>
interface, which, despite the similarity in name to classReadOnlyCollection
, does not even support indexed access, making it fundamentally unsuitable for providing array-like access.)
1
@mortb: Unfortunately,IReadOnlyCollection
doesn't support indexed access, so it can't be used here. Additionally, likeIReadOnlyList
(which does have indexed access) it is susceptible to element manipulation by casting back tostring
. In other words:ReadOnlyCollection
(which you cannot cast a string array to) is the most robust solution. Not using a getter is an option (and I've updated the answer to note that), but with public data it's probably better to stick with a property.
– mklement0
Apr 6 '17 at 12:07
add a comment |
A .NET Framework v4.5+ solution that improves on tdbeckett's answer:
using System.Collections.ObjectModel;
// ...
public ReadOnlyCollection<string> Titles { get; } = new ReadOnlyCollection<string>(
new string { "German", "Spanish", "Corrects", "Wrongs" }
);
Note: Given that the collection is conceptually constant, it may make sense to make it static
to declare it at the class level.
The above:
Initializes the property's implicit backing field once with the array.
Note that
{ get; }
- i.e., declaring only a property getter - is what makes the property itself implicitly read-only (trying to combinereadonly
with{ get; }
is actually a syntax error).Alternatively, you could just omit the
{ get; }
and addreadonly
to create a field instead of a property, as in the question, but exposing public data members as properties rather than fields is a good habit to form.
Creates an array-like structure (allowing indexed access) that is truly and robustly read-only (conceptually constant, once created), both with respect to:
preventing modification of the collection as a whole (such as by removing or adding elements, or by assigning a new collection to the variable).
preventing modification of individual elements.
(Even indirect modification isn't possible - unlike with anIReadOnlyList<T>
solution, where a(string)
cast can be used to gain write access to the elements, as shown in mjepsen's helpful answer.
The same vulnerability applies to theIReadOnlyCollection<T>
interface, which, despite the similarity in name to classReadOnlyCollection
, does not even support indexed access, making it fundamentally unsuitable for providing array-like access.)
1
@mortb: Unfortunately,IReadOnlyCollection
doesn't support indexed access, so it can't be used here. Additionally, likeIReadOnlyList
(which does have indexed access) it is susceptible to element manipulation by casting back tostring
. In other words:ReadOnlyCollection
(which you cannot cast a string array to) is the most robust solution. Not using a getter is an option (and I've updated the answer to note that), but with public data it's probably better to stick with a property.
– mklement0
Apr 6 '17 at 12:07
add a comment |
A .NET Framework v4.5+ solution that improves on tdbeckett's answer:
using System.Collections.ObjectModel;
// ...
public ReadOnlyCollection<string> Titles { get; } = new ReadOnlyCollection<string>(
new string { "German", "Spanish", "Corrects", "Wrongs" }
);
Note: Given that the collection is conceptually constant, it may make sense to make it static
to declare it at the class level.
The above:
Initializes the property's implicit backing field once with the array.
Note that
{ get; }
- i.e., declaring only a property getter - is what makes the property itself implicitly read-only (trying to combinereadonly
with{ get; }
is actually a syntax error).Alternatively, you could just omit the
{ get; }
and addreadonly
to create a field instead of a property, as in the question, but exposing public data members as properties rather than fields is a good habit to form.
Creates an array-like structure (allowing indexed access) that is truly and robustly read-only (conceptually constant, once created), both with respect to:
preventing modification of the collection as a whole (such as by removing or adding elements, or by assigning a new collection to the variable).
preventing modification of individual elements.
(Even indirect modification isn't possible - unlike with anIReadOnlyList<T>
solution, where a(string)
cast can be used to gain write access to the elements, as shown in mjepsen's helpful answer.
The same vulnerability applies to theIReadOnlyCollection<T>
interface, which, despite the similarity in name to classReadOnlyCollection
, does not even support indexed access, making it fundamentally unsuitable for providing array-like access.)
A .NET Framework v4.5+ solution that improves on tdbeckett's answer:
using System.Collections.ObjectModel;
// ...
public ReadOnlyCollection<string> Titles { get; } = new ReadOnlyCollection<string>(
new string { "German", "Spanish", "Corrects", "Wrongs" }
);
Note: Given that the collection is conceptually constant, it may make sense to make it static
to declare it at the class level.
The above:
Initializes the property's implicit backing field once with the array.
Note that
{ get; }
- i.e., declaring only a property getter - is what makes the property itself implicitly read-only (trying to combinereadonly
with{ get; }
is actually a syntax error).Alternatively, you could just omit the
{ get; }
and addreadonly
to create a field instead of a property, as in the question, but exposing public data members as properties rather than fields is a good habit to form.
Creates an array-like structure (allowing indexed access) that is truly and robustly read-only (conceptually constant, once created), both with respect to:
preventing modification of the collection as a whole (such as by removing or adding elements, or by assigning a new collection to the variable).
preventing modification of individual elements.
(Even indirect modification isn't possible - unlike with anIReadOnlyList<T>
solution, where a(string)
cast can be used to gain write access to the elements, as shown in mjepsen's helpful answer.
The same vulnerability applies to theIReadOnlyCollection<T>
interface, which, despite the similarity in name to classReadOnlyCollection
, does not even support indexed access, making it fundamentally unsuitable for providing array-like access.)
edited Nov 24 '18 at 14:24
answered Apr 5 '17 at 13:51
mklement0mklement0
133k21246284
133k21246284
1
@mortb: Unfortunately,IReadOnlyCollection
doesn't support indexed access, so it can't be used here. Additionally, likeIReadOnlyList
(which does have indexed access) it is susceptible to element manipulation by casting back tostring
. In other words:ReadOnlyCollection
(which you cannot cast a string array to) is the most robust solution. Not using a getter is an option (and I've updated the answer to note that), but with public data it's probably better to stick with a property.
– mklement0
Apr 6 '17 at 12:07
add a comment |
1
@mortb: Unfortunately,IReadOnlyCollection
doesn't support indexed access, so it can't be used here. Additionally, likeIReadOnlyList
(which does have indexed access) it is susceptible to element manipulation by casting back tostring
. In other words:ReadOnlyCollection
(which you cannot cast a string array to) is the most robust solution. Not using a getter is an option (and I've updated the answer to note that), but with public data it's probably better to stick with a property.
– mklement0
Apr 6 '17 at 12:07
1
1
@mortb: Unfortunately,
IReadOnlyCollection
doesn't support indexed access, so it can't be used here. Additionally, like IReadOnlyList
(which does have indexed access) it is susceptible to element manipulation by casting back to string
. In other words: ReadOnlyCollection
(which you cannot cast a string array to) is the most robust solution. Not using a getter is an option (and I've updated the answer to note that), but with public data it's probably better to stick with a property.– mklement0
Apr 6 '17 at 12:07
@mortb: Unfortunately,
IReadOnlyCollection
doesn't support indexed access, so it can't be used here. Additionally, like IReadOnlyList
(which does have indexed access) it is susceptible to element manipulation by casting back to string
. In other words: ReadOnlyCollection
(which you cannot cast a string array to) is the most robust solution. Not using a getter is an option (and I've updated the answer to note that), but with public data it's probably better to stick with a property.– mklement0
Apr 6 '17 at 12:07
add a comment |
Arrays are probably one of those things that can only be evaluated at
runtime. Constants must be evaluated at compile time. Try using "readonly"
instead of "const".
add a comment |
Arrays are probably one of those things that can only be evaluated at
runtime. Constants must be evaluated at compile time. Try using "readonly"
instead of "const".
add a comment |
Arrays are probably one of those things that can only be evaluated at
runtime. Constants must be evaluated at compile time. Try using "readonly"
instead of "const".
Arrays are probably one of those things that can only be evaluated at
runtime. Constants must be evaluated at compile time. Try using "readonly"
instead of "const".
answered Feb 28 '11 at 13:07
nemkenemke
1,43033051
1,43033051
add a comment |
add a comment |
For the sake of completeness, now we also have ImmutableArrays at our disposal.
This should be truly immutable:
public readonly static ImmutableArray<string> Tiles = ImmutableArray.Create(new { "German", "Spanish", "Corrects", "Wrongs" });
Requires System.Collections.Immutable NuGet reference
https://msdn.microsoft.com/en-us/library/mt452182(v=vs.111).aspx
add a comment |
For the sake of completeness, now we also have ImmutableArrays at our disposal.
This should be truly immutable:
public readonly static ImmutableArray<string> Tiles = ImmutableArray.Create(new { "German", "Spanish", "Corrects", "Wrongs" });
Requires System.Collections.Immutable NuGet reference
https://msdn.microsoft.com/en-us/library/mt452182(v=vs.111).aspx
add a comment |
For the sake of completeness, now we also have ImmutableArrays at our disposal.
This should be truly immutable:
public readonly static ImmutableArray<string> Tiles = ImmutableArray.Create(new { "German", "Spanish", "Corrects", "Wrongs" });
Requires System.Collections.Immutable NuGet reference
https://msdn.microsoft.com/en-us/library/mt452182(v=vs.111).aspx
For the sake of completeness, now we also have ImmutableArrays at our disposal.
This should be truly immutable:
public readonly static ImmutableArray<string> Tiles = ImmutableArray.Create(new { "German", "Spanish", "Corrects", "Wrongs" });
Requires System.Collections.Immutable NuGet reference
https://msdn.microsoft.com/en-us/library/mt452182(v=vs.111).aspx
answered Jul 25 '18 at 22:54
shurikshurik
638716
638716
add a comment |
add a comment |
As an alternative, to get around the elements-can-be-modified issue with a readonly array, you can use a static property instead. (The individual elements can still be changed, but these changes will only be made on the local copy of the array.)
public static string Titles
{
get
{
return new string { "German", "Spanish", "Corrects", "Wrongs"};
}
}
Of course, this will not be particularly efficient as a new string array is created each time.
add a comment |
As an alternative, to get around the elements-can-be-modified issue with a readonly array, you can use a static property instead. (The individual elements can still be changed, but these changes will only be made on the local copy of the array.)
public static string Titles
{
get
{
return new string { "German", "Spanish", "Corrects", "Wrongs"};
}
}
Of course, this will not be particularly efficient as a new string array is created each time.
add a comment |
As an alternative, to get around the elements-can-be-modified issue with a readonly array, you can use a static property instead. (The individual elements can still be changed, but these changes will only be made on the local copy of the array.)
public static string Titles
{
get
{
return new string { "German", "Spanish", "Corrects", "Wrongs"};
}
}
Of course, this will not be particularly efficient as a new string array is created each time.
As an alternative, to get around the elements-can-be-modified issue with a readonly array, you can use a static property instead. (The individual elements can still be changed, but these changes will only be made on the local copy of the array.)
public static string Titles
{
get
{
return new string { "German", "Spanish", "Corrects", "Wrongs"};
}
}
Of course, this will not be particularly efficient as a new string array is created each time.
edited Sep 22 '15 at 23:08
answered Sep 22 '15 at 23:00
HutchHutch
561514
561514
add a comment |
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%2f5142349%2fdeclare-a-const-array%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
static could be used, public static string Titles = new string { "German", "Spanish"};
– Ray Fan
May 23 '14 at 18:07