Seems like I can't do this:
private int[,] _table = new int[9, 9];
private ReadOnlyCollection<int[,]> _tableReadOnly = new ReadOnlyCollection<int[,]>(_table);
My idea is to have a property that let's the user read _table, but I don't want to let them change it, so I thought I could use ReadOnlyCollection for the matter.
The ReadOnlyCollection is a one dimensional collection. You could make a ReadOnlyCollection<ReadOnlyCollection<int>>, or make your own two dimensional wrapper class, something like:
public class ReadOnlyMatrix<T> {
private T[,] _data;
public ReadOnlyMatrix(T[,] data) {
_data = data;
}
public T this[int x, int y] {
get {
return _data[x, y];
}
}
}
The problem is you're trying to wrap a 2D mutable structure with a 1D read only structure. You'll need several levels of nesting to accomplish this.
ReadOnlyCollection<ReadOnlyCollection<int>>
The downside to this approach though is that it will essentially force you to have the entire table in memory twice. ReadOnlyCollection<T> requires a List<T> as the sole constructor argument. So you will end up copying each one of your rows into a new List<int>.
Another way to accomplish this though is to use a property indexer to return the value directly without allowing for mutation.
public int this[int i, int j] {
get { return _table[i,j]; }
}
This allows consumers to read the data without every having to mutate it.
You could do something like:
public class ReadOnly2DArray<T>
{
T[,] _array;
public ReadOnly2DArray(T[,] arrayToWrap)
{
_array = arrayToWrap;
}
public T this[int x, int y]
{
get { return _array[x, y]; }
}
}
possibly adding other methods of the Array class (Length property, GetLength method, ...) if you need them.
You'd then use it something like:
int[,] a = new int[2, 2];
ReadOnly2DArray<int> wrapper = new ReadOnly2DArray<int>(a);
int value = wrapper[0, 0]; // Can read values
//wrapper[0, 0] = value; // Won't compile
I'm not entirely sure I understand the direction you were taking, but based on your description of what you're trying to accomplish, it seems to me that you can just do the following:
private int[,] _table = new int[9, 9];
public int[,] Table
{
get
{
return _table;
}
}
Related
So let's say I have a helper class which contains methods that manipulate a collection:
public static void RemainingDegreeDistribution(IGraph graph, float[,] distArr)
{
int total = 0;
for(int i=0; i < graph.Edges.Count; i++)
{
int startRemDeg = graph.Edges[i].Start.RemDeg;
int endRemDeg = graph.Edges[i].End.RemDeg;
distArr[startRemDeg,endRemDeg]++;
distArr[endRemDeg, startRemDeg]++;
total = total+2;
}
for(int i=0; i < distArr.GetLength(0); i++)
{
for(int j=0; j < distArr.GetLength(1); j++)
{
distArr[i,j] /= total;
}
}
}
How can I change the code to allow the collection that is passed in to either be an array or one of my own collection classes?
The trouble is, the collection that is passed in must be 2-dimensional. There isn't an interface that I can implement in my own collection classes that arrays also implement.
I want to be able to reuse the code for both cases and avoid introducing lots of ugly conditional logic. I also need to avoid allocating memory so making some kind of wrapper class for arrays isn't acceptable. I also want to avoid using lists within lists as its so much simpler to work with normal 2d arrays and lists allocate too much memory for my purposes. It seems like this should be possible with indexers or something. Like is there a way to declare that "distArr" must be any type with an indexer that takes two arguments etc.?
There is no such interface. So you need to make your own, for instance:
public interface IMatrix<T>
{
int Rows { get; }
int Columns { get; }
ref T this[int row, int column] { get; }
}
and additionally of implementing it in your collection classes, create adapter for arrays (Adapter Pattern).
I know, I know, you said
I also need to avoid allocating memory so making some kind of wrapper class for arrays isn't acceptable.
I don't think a tiny short lived GC3 generation wrapper object will hurt your system, but anyway, the heap allocation can be avoided by implementing the wrapper as a struct:
public struct ArrayMatrix<T> : IMatrix<T>
{
readonly T[,] source;
public ArrayMatrix(T[,] source) => this.source = source;
public int Rows => source.GetLength(0);
public int Columns => source.GetLength(1);
public ref T this[int row, int column] => ref source[row, column];
}
and making your method generic (to avoid boxing of the struct):
public static void RemainingDegreeDistribution<TMatrix>(IGraph graph, TMatrix distArr)
where TMatrix : IMatrix<float>
{
int total = 0;
for (int i = 0; i < graph.Edges.Count; i++)
{
int startRemDeg = graph.Edges[i].Start.RemDeg;
int endRemDeg = graph.Edges[i].End.RemDeg;
distArr[startRemDeg, endRemDeg]++;
distArr[endRemDeg, startRemDeg]++;
total = total + 2;
}
for (int i = 0; i < distArr.Rows; i++)
{
for (int j = 0; j < distArr.Columns; j++)
{
distArr[i, j] /= total;
}
}
}
To make it easier to be used with arrays, you could add a helper method:
public static class ArrayMatrix
{
public static ArrayMatrix<T> ToMatrix<T>(this T[,] source) => new ArrayMatrix<T>(source);
}
and even provide overload of your method with array argument:
public static void RemainingDegreeDistribution(IGraph graph, float[,] distArr)
=> RemainingDegreeDistribution(graph, distArr.ToMatrix());
If you need to represent point in 2D space i suggesto you to use Point data structure.
https://learn.microsoft.com/en-us/dotnet/api/system.drawing.point?view=netframework-4.7.2
Try overloading if you also would pass an array of coordinates and points :
public static Method ( float[,] coordinates )
{
//generate array of Points starting from coordinates , points.Add ( new Point(coordinate[i,j]) )
}
public static Method ( Point[] points)
{
//actual logic
}
How I do it currently:
class Foo
{
public int[] A { get { return (int[])a.Clone(); } }
private int[] a;
}
I think it's bad because it creates a clone and casts whenever I access it. I know I can work around it by introducing an additional variable like this
var foo = new Foo();
// as soon as you have to access foo.A do this
int[] fooA = foo.A;
// use fooA instead of foo.A from now on
but still it just looks bad.
I also dislike the java way of encapsulating
int get(int index) { return a[index]; }
because I dont get the advantages of using an array.
Is there any better way to do this?
edit: I want an array of encapsulated variables. The problem is that
public int[] A { get; private set; }
is not an array of encapsulated variables because I can modify elements of the array from outside of the class.
edit: It should also work with multidimensional arrays
Arrays implement IReadOnlyList<T> which exposes all of the relevant information you want (an iterator, an indexer, count, etc.) without exposing any of the mutable functionality of the array.
class Foo
{
public IReadOnlyList<int> A { get { return a; } }
private int[] a;
}
alternatively, you could use an iterator/generator to return the items as requested:
class Foo
{
public IEnumerable<int> A
{
get
{
foreach (int i in a)
yield return i;
}
}
private int[] a;
}
... then iterate over them normally or use LINQ to get them as a new array or other type of collection:
int[] arr = foo.A.ToArray();
Why not expose A as a implementation of IReadOnlyList
class Foo
{
public IReadOnlyList<int> A { get { return a; } }
private int[] a;
}
This allows you to return the Array as a collection where they can use the index but cannot change the contents of the array itself.
sounds like you need an indexer
...
public int this[int i]{
get{return a[i];}
set{a[i] = value;}
}
....
https://msdn.microsoft.com/en-us/library/6x16t2tx.aspx
I am trying to initialize an array that is inside a class.
I am getting the "object reference is not set to an instance of an object" error.
Here's my NPC class:
namespace EngineTest
{
public class npcs
{
public int tileX, tileY, layerZ;
public int textureX, textureY;
public string ID;
public string state;
public int direction; //0 = south, 1= west, 2 = north, 3= east
public int moveLimitTimer;
public int animationCurrentFrame;
public int animationResetTimer;
public pathPotentials[, ,] pathPotential; (this is the array)
}
}
Here is the pathPotentials Class
namespace EngineTest
{
public class npcs
{
public int tileX, tileY, layerZ;
public int textureX, textureY;
public string ID;
public string state;
public int direction; //0 = south, 1= west, 2 = north, 3= east
public int moveLimitTimer;
public int animationCurrentFrame;
public int animationResetTimer;
public pathPotentials[, ,] pathPotential = new pathPotentials[Program.newMapWidth, Program.newMapHeight, Program.newMapLayers];
}
}
I tried to initialize it by this code:
for (z = 0; z < Program.newMapLayers; z++)
{
for (x = 0; x < Program.newMapWidth; x++)
{
for (y = 0; y < Program.newMapHeight; y++)
{
if(Program.tileNpcs[x, y, z].npcs.Count > 0)
{
Program.tileNpcs[x, y, z].npcs[0].pathPotential[Program.newMapWidth, Program.newMapHeight, Program.newMapLayers] = new pathPotentials();
}
}
}
}
But it doesn't work. What should I do?
Thanks in advance.
In C# (and a lot of programming languages of this type), arrays have a fixed length. In C#, arrays are stored as an object, with a set of values. Assigning to an element in an array is like altering a field of an object - you need to define the array explicitly first. If you don't define it explicitly, C# doesn't know how much memory to assign the array, which can cause a lot of problems when structuring memory.
You declare a 3-dimensional array, but you don't define it:
public pathPotentials[, ,] pathPotential;
What you need is something like this:
public pathPotentials[, ,] pathPotential = new pathPotentials[Program.newMapWidth, Program.newMapHeight, Program.newMapLayers];
This tells C# exactly how big to make your array.
However, this does not allow you to change the size of the array once it is declared (at least without clearing it by redefining it). If you need the size to change at runtime, then C# provides a class List, which takes a generic parameter (which in this case is fairly complex, for a 3D grid). You can declare something like this with Lists like so:
public List<List<List<pathPotentials>>> pathPotential = new List<List<List<pathPotentials>>>();
This gives you a nested list of lists of lists. The innermost list might be z, the outermost x. To get data from this, you can specify an inex, but you can no longer use [x,y,z] as the notation, and must instead use [x][y][z], as you are accessing a list to get another list item, and then accessing that list to get a second list item, and then accessing that one to get your object.
Hopefully, this has helped you to understand what went wrong, why your code doesn't work, and how you might fix it.
the code is bound to give you the error, since before initializing you are referencing a particular item of array. instead of your statement:
Program.tileNpcs[x, y, z].npcs[i].pathPotential[Program.newMapWidth, Program.newMapHeight, Program.newMapLayers] = new pathPotentials();
You should have it this way:
Program.tileNpcs[x, y, z].npcs[i].pathPotential = new pathPotentials[Program.newMapWidth, Program.newMapHeight, Program.newMapLayers];
Hope that helps..
i have recently stumbled upon a project(8-puzzle solver using A* alg) in which some codes are weird to me , because i have never seen the likes of it before .
what does this line mean ? what is this ?!
this[StateIndex]
whats this notation ? i cant undersand it at all !
i posted a sample of the class so that you can see it almost all together .
and one more question , is it not wrong to have a class implemented like StateNode? it used only a constructor to initialize its fields , and yet worst, declared them all public ! should he/she not have implemented Propertise for this task?
public enum Direction
{
Up = 1, Down = 2, Left = 3, Right = 4, UpUp = 5, DownDown = 6, LeftLeft = 7, RightRight = 8, Stop = 9
}
class StateNode
{
public int Parent;
public List<int> Childs;
public Direction Move;
public Direction ParentMove;
public byte[,] State;
public byte Depth;
public byte NullRow;
public byte NullCol;
public StateNode()
{ }
public StateNode(int NewParent, Direction NewMove, Direction ParentMove, byte NewDepth, byte NewNullRow, byte NewNullCol)
{
this.Parent = NewParent;
this.State = new byte[5, 5];
this.Move = NewMove;
this.ParentMove = ParentMove;
this.Depth = NewDepth;
this.NullRow = NewNullRow;
this.NullCol = NewNullCol;
this.Childs = new List<int>();
}
}
class StateTree : List<StateNode>
{
public static long MakedNodes;
public static long CheckedNodes;
public static byte MaxDepth;
public List<int> Successor1(int StateIndex)
{
List<int> RetNodes = new List<int>();
StateNode NewState = new StateNode();
//Up
if (this[StateIndex].NullRow + 1 <= 3 && this[StateIndex].ParentMove != Direction.Up)
{
NewState = ChangeItemState(this[StateIndex], StateIndex, Direction.Up, Direction.Down, Convert.ToByte(this[StateIndex].Depth + 1), this[StateIndex].NullRow, this[StateIndex].NullCol, Convert.ToByte(this[StateIndex].NullRow + 1), this[StateIndex].NullCol);
this.Add(NewState);
RetNodes.Add(this.Count - 1);
StateTree.MakedNodes++;
this[StateIndex].Childs.Add(this.Count - 1);
if (NewState.Depth > StateTree.MaxDepth)
StateTree.MaxDepth = NewState.Depth;
}
//Down
//Left
//Right
return RetNodes;
}
}
In your concrete case it's just access to the element, as it used inside the class that is derived from the List<T>
But it can be also indexer which enables index acces to your class object.
For example declare class like this:
public class ListWrapper
{
private List<int> list = ...
public int this[int index]
{
return list[index];
}
}
and after use it like
var lw = new ListWrapper();
//fill it with data
int a = lw[2]; //ACCESS WITH INDEX EVEN IF THE TYPE IS NOT COLLECTION BY ITSELF
this[StateIndex] is using the current class' indexer property. The indexer property is what allows you to access an element in a collection or list object as if it was an array. For instance:
List<string> strings = new List<string>();
strings.Add("Item 1");
strings.Add("Item 2");
strings.Add("Item 3");
string x = strings[0]; // Returns the first item in the list ("Item 1")
When you want to access the indexer property of your own class, however, you have to preface it with the this keyword. You'll notice that in your example, the StateTree class doesn't implement an indexer property, so that may be adding to your confusion. The reason it works is because StateTree inherits from List<StateNode> which does implement an indexer property.
But don't get confused between classes with indexer properties and arrays. Arrays are a completely different thing, though the syntax is similar. An array is a list of objects which can be accessed by an index. An indexer property is an unnamed property of a single object that acts as an array. So for instance, List<string> has an indexer property, so you can access the items it contains using the same syntax as an array index (as shown in the above example). However, you can still make an array of List<string> objects. So for instance:
List<string> strings1 = new List<string>();
strings1.Add("Item 1.1");
strings1.Add("Item 1.2");
List<string> strings2 = new List<string>();
strings2.Add("Item 2.1");
strings2.Add("Item 2.2");
List<string>[] stringsArray = new List<string>[] { strings1, strings2 };
object result;
result = stringsArray[0]; // Returns strings1
result = stringsArray[0][1]; // Returns "Item 1.2"
result = stringsArray[1][0]; // Returns "Item 2.1"
As far as StateNode goes, there's nothing technically wrong with it, and it's not unusual to have a constructor that initializes all the field values, but it's always better to use properties instead of public fields.
its Indexed Properties in C# .net .
you can check Tutorial : http://msdn.microsoft.com/en-us/library/aa288464(v=vs.71).aspx check here
this[StateIndex] is pointing to an element within the class. Because StateTree inherits from a List<T>, you have a collection that's accessible by index (in this case this[N] where N is the element's index.
this[StateIndex] is how you give a class and indexed property e.g
public class IndexedClass
{
private List<String> _content;
public IndexedClass()
{
_content = new List<String>();
}
public Add(String argValue)
{
_content.Add(argValue);
}
public string this[int index]
{
get
{
return _content[index];
}
set
{
_content[Index] = value;
}
}
}
so now you can do
IndexedClass myIndex = new IndexedClass();
myIndex.Add("Fred");
Console.Writeline(myIndex[0]);
myIndex[0] = "Bill";
Console.Writeline(myIndex[0]);
As for statenode if it's local to the class (a helper) then you could argue it as okay, I don't like it though, another ten minutes work it could be done properly. If it's public in the assembly, then it's not accpetable in my opinion. But that is an opinion.
Is it possible to do somethink like
public class TestClass
{
public List<double> preTvoltage
{
get
{
return preTvoltage;
}
set
{
preTvoltage.Add(this); //how to add to the List??
}
}
}
The reason I want to do this (I do not know if this is a best method, just as far as my knowledge allows) because I have to get data from xml files that do not have always same number of data in them.
Later I want to fill a ListView rows and using list I can count how many items are and how many columns will be needed.
Here is a schematic of xml file:
and there are also Trigger and PostTrigger nodes in xml file with same data sorting.
and here is the listview I want to achive:
Link to full size image
So, there are some pin groups and each pingroup has lots of data, the above code I gave, was just to hold 1 of the voltage nodes in xml file.
I am pretty much listening for your ideas!
Thanks.
No, and it defies usage of properties - you should implement it as an Add (or similarly aptly named) method.
You can't add this, because this is a TestClass, not a double; and you can't add value, as otherwise suggested, because that is a List<double>, and Add requires a double.
It's not clear how you would use this, but it looks like a very bad idea to me. Setting a collection as a property is slightly unusual already, but it's even odder for that set operation to mutate the list. It's additionally weird that you're not using the value variable within the setter... why not?
You should consider what the calling code would look like, and whether that's really the clearest way of expressing the semantics you want.
set { preTvoltage.AddRange(value); }
As Jon Skeet is saying, this is not what you should do. Instead, do
TestClass t = new TestClass();
t.PreTvoltage.Add(...);
declaring the property as
public List<double> PreTvoltage
{
get { return preTvoltage; }
}
The type of a getter and setter must match.
You could have:
public List<double> preTvoltage
{
get
{
return preTvoltage;
}
set
{
preTvoltage.AddRange(value); //add all items in list assigned.
}
}
However, this seems like a bad idea as it would be confusing to users why the value got did not match the value just set. I would have the two operations as separate members, and the setter either not exist or else overwrite the existing preTvoltage entirely.
You can not implement it like this, the preferable way is to make collection controls like:
private IList<double> _preTvoltage = new List<double>();
public IEnumerable<double> preTvoltage
{
get
{
return preTvoltage.AsEnumerable();
}
}
public void AddTvoltage(double item)
{
_preTvoltage.Add(item);
}
Well I managed to solve my problem this way:
public class ITestData
{
public string pinName { get; set; } //Name of the pin
public double stressLevel { get; set; } //Stress level for latchup
public int psuCount { get; set;} //Number of PSU's
public List<double[]> preTrigger = new List<double[]>();
public List<double[]> inTrigger = new List<double[]>();
public List<double[]> postTrigger = new List<double[]>();
public void AddPreTrigger(double volt, double curr)
{
double[] data = new double[2];
data[0] = volt;
data[1] = curr;
preTrigger.Add(data);
}
public void AddInTrigger(double volt, double curr)
{
double[] data = new double[2];
data[0] = volt;
data[1] = curr;
inTrigger.Add(data);
}
public void AddPostTrigger(double volt, double curr)
{
double[] data = new double[2];
data[0] = volt;
data[1] = curr;
postTrigger.Add(data);
}
}