Access updated array from constructor - c#

I have a parameterized constructor and a default constructor. They both create a new object array with x length, however, when I try to access the array in the Add method, it returns the value "null". I can't initialize the array in the fields because I don't know what size the user wants it to be, but I don't know how to access the 'updated' array later in the code. I get a NullReferenceException() on the line of code: if (count > data.Length) because data has the value null.
class CustomList
{
private int count;
private String[] data;
public int Count
{
get { return count; }
}
public CustomList(int arrayNum)
{
String[] data = new String[arrayNum];
}
public CustomList(): this(4)
{
}
public void Add (String item)
{
if (count > data.Length)
{
String[] temp = new String[count * 2];
for (int i = 0; i < data.Length; i++)
{
temp[i] = data[i];
}
data = temp;
}
data[count] = item;
count++;
}

Change this:
public CustomList(int arrayNum)
{
String[] data = new String[arrayNum];
}
To this:
public CustomList(int arrayNum)
{
data = new String[arrayNum];
}
You have accidentally created a local variable in the constructor which is being assigned to instead of the field that you wanted to assign to.

Change your code.
Your data object in constructor is local variable.
And you are not initializing your instance data object.
class CustomList
{
private int count;
private String[] data;
public int Count
{
get { return count; }
}
public CustomList(int arrayNum)
{
data = new String[arrayNum];
}
public CustomList(): this(4)
{
}
public void Add (String item)
{
if (count > data.Length)
{
String[] temp = new String[count * 2];
for (int i = 0; i < data.Length; i++)
{
temp[i] = data[i];
}
data = temp;
}
data[count] = item;
count++;
}

Related

Linked List/Node Clas - Adding User Input to Linked List

I have the user inputting a string which is stored in the variable 'word'. I now want to add this stored variable to the linked list. I've tried using
LinkedList<string>.Add(word);
To add the variable to the linked this but it isn't working and is returning the error "An object reference is required for the non-static field, method or property 'LinkedList.Add(string)"
I'm assuming it has something to do with my linked list but I'm not to sure.
Any help or ideas on the issue would be great.
using System;
using System.Collections.Generic;
using System.Text;
namespace project
{
public class LinkedList<TData>
{
private Node<TData> head;
private int count;
public LinkedList(string word)
{
this.head = null;
this.count = 0;
}
public bool Empty
{
get { return this.count == 0; }
}
public int Count
{
get { return this.count; }
}
public TData this[int index]
{
get { return this.Get(index); }
}
public TData Add(int index, TData data)
{
if (index < 0)
throw new ArgumentOutOfRangeException("Index: " + index);
if (index > count)
index = count;
Node<TData> current = this.head;
if (this.Empty || index == 0)
{
this.head = new Node<TData>(data, this.head);
}
else
{
for (int i = 0; i < index - 1; i++)
{
current = current.Next;
current.Next = new Node<TData>(data, current.Next);
}
}
count++;
return data;
}
public TData Add(TData data)
{
return this.Add(count, data);
}
public TData Remove(int index)
{
if (index < 0)
throw new ArgumentOutOfRangeException("Index: " + index);
if (this.Empty)
return default(TData);
if (index >= this.count)
index = count - 1;
Node<TData> current = this.head;
TData result;
if (index == 0)
{
result = current.Data;
this.head = current.Next;
}
else
{
for (int i = 0; index < index - 1; i++) ;
current = current.Next;
result = current.Next.Data;
current.Next = current.Next.Next;
}
count--;
return result;
}
public void Clear()
{
this.head = null;
this.count = 0;
}
public int IndexOf(TData data)
{
Node<TData> current = this.head;
for (int i = 0; i < this.count; i++)
{
if (current.Data.Equals(data))
return i;
current = current.Next;
}
return -1;
}
public bool Contains(TData data)
{
return this.IndexOf(data) >= 0;
}
public TData Get(int index)
{
if (index < 0)
throw new ArgumentOutOfRangeException("Index: " + index);
if (this.Empty)
return default(TData);
if (index >= this.count)
index = this.count - 1;
Node<TData> current = this.head;
for (int i = 0; i < index; i++)
current = current.Next;
return current.Data;
}
}
}
using System;
using System.Collections.Generic;
using System.Text;
namespace project
{
public class Node<TData>
{
private Node<TData> next { get; set; }
public Node(TData data, Node<TData> next)
{
this.Data = data;
this.next = next;
}
public TData Data { get; set; }
public Node<TData> Next
{
get { return this.next; }
set { this.next = value; }
}
}
}
using System;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
namespace project
{
class Program
{
static void Main(string[] args)
{
string word;
Console.WriteLine("Please enter a word");
word = Console.ReadLine();
Console.WriteLine("You typed: " + word);
Console.ReadKey();
var list = new LinkedList<string>(word);
LinkedList<string>.Add(word);
}
}
}
Change this:
var list = new LinkedList<string>(word);
LinkedList<string>.Add(word);
To this:
var list = new LinkedList<string>();
list.Add(word);
list is your linked list object in memory. Whenever you want to do something with your list, you use the variable reference list, not the name for the kind of object it is. The reason we use the name of the variable rather than the name of the kind is because we might very well want to have two or more of them in our program:
var postiveList = new LinkedList<string>();
var negativeList = new LinkedList<string>();
positiveList.Add("happy");
negativeList.Add("sad");
It's only possible to use the name of the type(kind), when you're using something declared as static - and nothing in your program is static that I can point to and make a suitable demonstration of. Something you'll have probably used though:
int x = Convert.ToInt32("1234");
Convert here is static, the name of a type of class. You don't need to make a new Convert before you use it, and you can't have (nor need) more than one Convert in a program, so it makes sense to have it be static (only one of them)
Some things are both static and not:
var startTime = new DateTime(1970,1,1);
var endTime = DateTime.UtcNow;
startTime and endTime are both instances of a DateTime. To get the end time, however, we used a static property UtcNow of the DateTime type. It created a new DateTime for us based on the value of the computer clock and returned it. We didn't need for any other datetime to exist before we did this. If it helps, think of these static things as being like factories that churn out manufactured objects on demand. There is only one factory, and the things it makes are always the same kind of thing but it can make millions of them
Also change this:
public LinkedList(string word)
{
this.head = null;
this.count = 0;
}
To this:
public LinkedList()
{
this.head = null;
this.count = 0;
}
There's no point asking for something and then not doing anything with it - it just makes the thing that asks harder to use. I get the feeling you didn't write LinkedList, but you might have added this in while trying to get a word into it
you write:
LinkedList<string>.Add(word);
This is an attempt to call a static method Add on the type LinkedList<string>. And the compiler is telling you that this is a instance method and not a static method. I.e. you want to call:
list.Add(word);
Also, the constructor
public LinkedList(string word)
takes a string, but does not do anything with it. This parameter should probably be removed.

Having trouble creating random values

So I created Pairs class that contains int and double and I want to create an array of them with my
array class by creating random values, but I'm getting System.NullReferenceException at Line 19 of
my array class.
Here's my pair class
class Pair
{
public int integer = 0;
public double doubl = 0.0;
public Pair(int integer, double doubl)
{
this.integer = integer;
this.doubl = doubl;
}
public Pair()
{
}
public int Integer() { return integer; }
public double Doubl() { return doubl; }
}
And this is my array class and the abstract class
class MyDataArray : DataArray
{
Pair[] data;
int operations = 0;
public MyDataArray(int n, int seed)
{
data = new Pair[n];
Random rand = new Random(seed);
for (int i = 0; i < n; i++)
{
data[i].integer = rand.Next(); //I get error here
data[i].doubl = rand.NextDouble();
}
}
public int integer(int index)
{
return data[index].integer;
}
public double doubl(int index)
{
return data[index].doubl;
}
}
abstract class DataArray
{
public int operations { get; set; }
public abstract void Swap(int i, int j);
public abstract void Swap2(int i, int high);
}
Also is it even worth it using this abstract class I used this from a reference that my university
provided. I have to create an quicksort algorithm that sorts pairs in arrays and linked lists and analyze it.
data = new Pair[n];
This creates a new array of null references.
The loop should be
for (int i = 0; i < n; i++)
{
data[i] = new Pair(rand.Next(), rand.NextDouble())
}
While we are looking at your code: you are making a good attempt here to make an immutable pair, but it could be better. What you want is:
class Pair
{
public Pair(int integer, double doubl)
{
this.Integer = integer;
this.Double = doubl;
}
public int Integer { get; private set; }
public double Double { get; private set; }
}
Shorter, safer, clearer.
The issue with your code is that you are only initializing the array of data in MyDataArray. When creating an array of instances, it only initializes references for the array, not the actual instances to be in the array. Those references all point to null. So when you do try to set the integer member of the i'th Pair instance in the data array:
...
data[i].integer = rand.Next();
...
You are actually trying to set the integer member of null, which does not exist.
...
null.integer = rand.Next();
...
To fix this, simply create a new instance of Pair for each index of data in your loop.
...
for (int i = 0; i < n; i++)
{
data[i] = new Pair();
data[i].integer = rand.Next();
data[i].doubl = rand.NextDouble();
}
...
Even better, you can use the constructor you've made where it takes parameters to set integer and doubl upon construction to simplify the code in your loop.
...
for (int i = 0; i < n; i++)
{
data[i] = new Pair(rand.Next(), rand.NextDouble());
}
...

encapsulation of an array of objects c#

I would like to create an array of objects. Each object has it's own int array.
For each object I assign values to it's array ONLY with keys given by myself (example: li[i].V[10] = 1; li[i].V[50] = 10; )
Can someone tell me how to do that? Can I do that without using Lists?
The second case is analogical to first. I would like to know how to assign values of object's List
using setter.
I tried to do that by myself. Unfortunately My code crashed cuz I don't know how to set the dimension of V and Word:
class CFiles
{
//private int[] v=new int[5];//dont want to specify the dimention of array here
private int[] v;//vector of file
private List<string> words;
public CFiles()
{
words = Words;
v = new int[50];
v = V;
}
public int[] V { get; set; }
public List<string> Words { get; set; }
}
class Program
{
static void Main(string[] args)
{
CFiles[] li = new CFiles[2];
for(int i=0;i<li.Length;i++)
{
li[i]=new CFiles();
li[i].V[10] = 1;
li[i].V[50] = 10;
li[i].V[50] = 15;
li[i].Words.Add("a");
li[i].Words.Add("ab");
li[i].Words.Add("abc");
}
for (int i = 0; i < li.Length; i++)
{
for(int j=0;j<li[i].V.Length;j++)
{
Console.WriteLine(li[i].V[j]);
}
}
Console.WriteLine();
}
}
Your constructor isn't right and your properties aren't quite right. You might want something more like this:
class CFiles
{
//private int[] v=new int[5];//dont want to specify the dimention of array here
private int[] v;
public int[] V { get { return v; } set { v = value; } }
private List<string> words;
public List<string> Words { get { return words; } set { words = value; } }
public CFiles()
{
words = new List<string>();
v = new int[51]; //needs to be 51 if you are going to assign to index 50 below
}
}
Other than those issues, your code seems to do what you want. You have an array of objects where each object has its own int array (in addition to a string of strings).
Is that not what you want?

How to set a list within an array

I initiated a multidimensional array:
private byte[,] grid = new byte[9, 9];
I want to hold a byte List with some values, for each cell withing the existing grid.
I know a 3 dimensional array would be handy here. But since the list with invalid values is dynamical, I would like to use a List instead of an array.
Edit: To give some context here. I'm making a sudoku, which is represented by a multidimensional array. Since I would like to solve the sudoku programmatically and I'm using the backtrack algorithm, I need to remember the digits that where invalid for each cell.
So each cell should consist of a value and a List. I could probably just put the actual field as first value in the list. But never know if there is an actual clean solution :)
var grid = new List<byte>[9,9];
for (int i = 0; i < 9; i++)
for (int j = 0; j < 9; j++)
grid[i, j] = new List<byte>();
After that every item of 9x9 array contains an empty List<byte>.
However, I would suggest creating a class like Field
public class Field
{
public byte Value { get; set; }
public List<byte> List { get; set; }
public Field()
{
List = new List<byte>();
}
}
And use it instead of just List<byte>:
var grid = new Field[9, 9];
for (int i = 0; i < 9; i++)
for (int j = 0; j < 9; j++)
grid[i, j] = new Field();
If I understand you correctly you need a list of bytes in a list?
Try this:
List<List<byte>> listOfBytesInList = new List<List<byte>>();
Update
You can implement a own class that uses internal a list of bytes.
I'm too late, but regardless I post my solution anyway.
public class ByteFieldList
{
private readonly List<byte> _interalBytes;
public ByteFieldList()
: this(4, 0)
{
}
public ByteFieldList(byte fieldValue)
: this(4, fieldValue)
{
}
public ByteFieldList(int capacity, byte fieldValue)
{
FieldValue = fieldValue;
_interalBytes = new List<byte>(capacity);
}
public byte FieldValue { get; set; }
public ByteFieldList Add(byte b)
{
_interalBytes.Add(b);
return this;
}
public void AddRange(byte[] bytes)
{
foreach (var b in bytes)
Add(b);
}
public ByteFieldList Remove(byte b)
{
_interalBytes.Remove(b);
return this;
}
public byte this[int index]
{
get { return _interalBytes[index]; }
}
public byte[] GetAllInvalid()
{
return _interalBytes.ToArray();
}
}
public void Usage()
{
ByteFieldList byteFieldList = new ByteFieldList(5);
byteFieldList.Add(5).Add(4).Add(8);
byteFieldList.AddRange(new byte[] { 7, 89, 4, 32, 1 });
var invalids = byteFieldList.GetAllInvalid(); // get 5, 4, 8, 7, 89, 4, 32, 1
byteFieldList.FieldValue = 4;
}

NullReferenceException, how do I handle this?

I'm getting this error in C# while trying to build an importer for a tilemap. It's supposed to read files formatted like this;
DatMapName!
6|4
SpritePageID:SpriteID:OffsetX:OffsetY|SpritePageID:SpriteID:OffsetX:OffsetY SpritePageID:SpriteID:OffsetX:OffsetY
SpritePageID:SpriteID:OffsetX:OffsetY|SpritePageID:SpriteID:OffsetX:OffsetY SpritePageID:SpriteID:OffsetX:OffsetY
into a data structure built up like this;
map
MapTile[MapSizeX, MapSizeY]
Tile[Sprites on tile]
- string SpritePageID
- int SpriteID
- Vector2 Offset
Basically it has the map name on the first line, X/Y size on the second, and then it has SpritePageID, spriteID, offsetx, offsetY separated by :, and multiple sprites per tile separated by |. Spaces delimit the different tiles.
However, during processing I get the following error;
Error 1 Building content threw NullReferenceException: Object reference not set to an instance of an object.
at LibTilePipelineExtension.LevelProcessor.Process(String input, ContentProcessorContext context) in C:\Projects\C#\XNA1\TileWorld\LibTilePipelineExtension\LevelProcessor.cs:line 45
at Microsoft.Xna.Framework.Content.Pipeline.ContentProcessor`2.Microsoft.Xna.Framework.Content.Pipeline.IContentProcessor.Process(Object input, ContentProcessorContext context)
at Microsoft.Xna.Framework.Content.Pipeline.BuildCoordinator.BuildAssetWorker(BuildItem item)
at Microsoft.Xna.Framework.Content.Pipeline.BuildCoordinator.BuildAsset(BuildItem item)
at Microsoft.Xna.Framework.Content.Pipeline.BuildCoordinator.RunTheBuild()
at Microsoft.Xna.Framework.Content.Pipeline.Tasks.BuildContent.RemoteProxy.RunTheBuild(BuildCoordinatorSettings settings, TimestampCache timestampCache, ITaskItem[] sourceAssets, String[]& outputContent, String[]& rebuiltContent, String[]& intermediates, Dictionary`2& dependencyTimestamps, KeyValuePair`2[]& warnings)
C:\Projects\C#\XNA1\TileWorld\TileWorld\TileWorldContent\tileworldtest1.tilemap TileWorld
Here's the code that's throwing this error.
string[] lines = input.Split(new char[] { '\n' });
// ------
// Clear out commented lines from the array. Turn it to a list, remove indices, turn back to array.
List<string> derp1 = new List<string>(lines);
for (int derp2 = 0; derp2 < derp1.Count; derp2++) {
if (derp1[derp2][0] == ' ' || derp1[derp2][0] == ';') {
derp1.RemoveAt(derp2);
derp2--;
}
}
lines = derp1.ToArray();
// ------
int rows = Convert.ToInt32(lines[1].Split('|')[0]);
int columns = Convert.ToInt32(lines[1].Split('|')[1]);
MapTile[,] res = new MapTile[rows, columns];
for (int i0 = 2; i0 < (rows + 2); i0++) {
string[] tiles = lines[i0].Split(' ');
for (int i1 = 0; i1 < columns; i1++) {
string[] tileSprites = tiles[i1].Split('|');
--> res[i0 - 2, i1].sprites = new Tile[tileSprites.Length]; <-- Exception
for (int i2 = 0; i2 < tileSprites.Length; i2++) {
string[] spriteData = tileSprites[i2].Split(':');
res[i0 - 2, i1].sprites[i2] = new Tile(spriteData[0], Convert.ToInt32(spriteData[1]), new Vector2(Convert.ToInt32(spriteData[2]), Convert.ToInt32(spriteData[3])));
}
}
}
return new Map(res, lines[0]);
These are the classes I use to make this tree. I removed the using statements to shorten this question.
//Map.cs
namespace LibTile {
public class Map {
public MapTile[,] grid { get; set; }
public string MapName { get; set; }
public Map(MapTile[,] value) {
grid = value;
}
public Map(MapTile[,] value, string name) {
grid = value;
MapName = name;
}
public MapTile GetTile(int row, int col) {
return grid[row, col];
}
public int Rows {
get {
return grid.GetLength(0);
}
}
public int Columns {
get {
return grid.GetLength(1);
}
}
}
}
.
//MapTile.cs
namespace LibTile {
public class MapTile {
public Tile[] sprites { get; set; }
public MapTile(Tile[] value) {
sprites = value;
}
}
}
.
//Tile.cs
namespace LibTile {
public class Tile {
public String SpritePageID;
public int SpriteID;
public Vector2 Offset;
public Tile(String spid, int sid, int ox, int oy) {
SpritePageID = spid;
SpriteID = sid;
Offset = new Vector2(ox,oy);
}
public Tile(String spid, int sid, Vector2 o) {
SpritePageID = spid;
SpriteID = sid;
Offset = o;
}
}
}
You create a new array of MapTile but you never initialize the individual elements. Try this:
res[i0 - 2, i1] = new MapTile(new Tile[tileSprites.Length]);
This will create a new MapTile object in each poition of the array. Not doing this was causing your null reference exception. I would also consider changing the constructor of MapTile to be parameterless and then just set MapTile.sprites as you were doing before.

Categories

Resources