Reputation: 9912
I am aware that in C# const can only be initialized at compile time. Which is related to what I am trying to do.
My objective is to write a constant array of constant objects in C#. How can I do that?
In order to explain my self, allow me to insert some code in C++ (I wrote some code some time ago) that explains what I am trying to do.
(In C++)
struct FD{
string name;
double CE[2];
};
const FD models[2]={
{"one",{2.0,1.0}},
{"two",{3.0,4.0}}
};
Seems very simple, right? How can I do something like this in C#?
EDIT: (Attempted answer)
I found that you can do something like this in C#
struct FD
{
public string name;
public double[] CE;
}
static readonly FD[] models= new[]
{
new FD(){name="one" , CE= new double[]{1.0,2.0 } },
new FD(){name="two", CE= new double[]{3.0,4.0}}
};
I wonder if this could be a good way to achieve my objective?
Upvotes: -1
Views: 4141
Reputation: 9912
In the end thanks to users Corak and Freggar I could come with something like this. (I suppose that model3 is the answer
Structs
struct FD
{
public string name;
public double[] CE;
}
struct FD2
{
public FD2(string name, IEnumerable<double>ce)
{
Name = name;
CE = new ReadOnlyCollection<double>(new List<double>(ce));
}
public readonly string Name;
public readonly IReadOnlyList<double> CE;
}
and the lists
//This solution does not give the entire constant structure as name and FD[0] can be changed
static readonly FD[] models= new[]
{
new FD(){name="one" , CE= new double[]{1.0,2.0 } },
new FD(){name="two", CE= new double[]{3.0,4.0}}
};
//Here name can not be changed but models2[0] can be
static readonly FD2[] models2 = new[]
{
new FD2("one",new double[]{1.0,2.0 }),
new FD2("two", new double[]{3.0,4.0 })
};
//This is the best solution
static readonly IReadOnlyList<FD2> models3 = new ReadOnlyCollection<FD2>(new[] {
new FD2("one",new double[]{1.0,2.0 }),
new FD2("two", new double[]{3.0,4.0 })
}
);
//This is also a good solution but models4[0].CE[0] can be changed
static readonly ReadOnlyCollection<FD> models4 = new ReadOnlyCollection<FD>(new[]
{
new FD(){name="one" , CE= new double[]{1.0,2.0 }},
new FD(){name="two", CE= new double[]{3.0,4.0}}
});
I guess models3 gives a good implementation to what I wanted to achieve.
Upvotes: -1
Reputation: 1056
Sadly in C# you cannot define arrays or structures as const
since the constructor can have runtime logic and therefore has to be executed at runtime. Your proposed solution is almost what you want, you just need a ReadonlyCollection<FD>
to encapsulate your Array:
using System.Collections.ObjectModel;
static readonly ReadOnlyCollection<FD> models = new ReadOnlyCollection<FD>(new[]
{
new FD(){name="one" , CE= new double[]{1.0,2.0 } },
new FD(){name="two", CE= new double[]{3.0,4.0}}
});
Now you cannot change the reference of models (readonly
) nor can you change the contents of it (ReadonlyCollection
). You also cannot change any members of the FD
instances since FD
is a struct
and the ReadonlyCollection
creates another layer of indirection, basically copying your struct:
models = new ReadOnlyCollection<FD>(new FD[] { }); // Error CS0198 A static readonly field cannot be assigned to
models[0] = new FD(); // Error CS0200 indexer is read only
models[0].name = "testname"; // Error CS1612 Cannot modify the return value
EDIT : I overlooked something, you can still change the array:
models[0].CE[0] = 1; // compiles just fine
If possible you want to make CE
readonly too, but I'm not sure if your API allows that
Upvotes: 2
Reputation: 34967
Thinking outside the box :P
Others are providing you with great ideas but if you want to have truly const 4 values then you could just:
const double FD_one_0 = 2.0;
const double FD_one_1 = 1.0;
const double FD_two_0 = 3.0;
const double FD_two_1 = 4.0;
Upvotes: 1