I would like an explanation what I'm doing wrong. I paste two block of codes; one is working another is not working. The first code works becasue the initial values are passed into the method "MyGreatMethod" I can see them:
public class Something
{
private int [] MyArray = new int [3];
public Something()
{
MyArray[0] = 100;
MyArray[1] = 200;
MyArray[2] = 300;
}
public void MyGreatMethod()
{
Console.WriteLine(MyArray[0] / 3);
Console.WriteLine(MyArray[1] / 3);
Console.WriteLine(MyArray[2] / 3);
}
}
but if I place values into "MyArray" this way(see below), the method "MyGreatMethod" gets NULLs from constructor, what I do wrong? Please help..
public class Something
{
private int [] MyArray = new int [3];
public Something()
{
int[] MyArray = {100,200,300};
}
public void MyGreatMethod()
{
Console.WriteLine(MyArray[0] / 3);
Console.WriteLine(MyArray[1] / 3);
Console.WriteLine(MyArray[2] / 3);
}
}
It is null because you haven't assigned the values to MyArray. Instead, you have created a new array and assigned it to a local variable with the same name.
You should remove the int[] from the constructor:
public class Something
{
private int [] MyArray = new int [3];
public Something()
{
MyArray = {100,200,300};
}
public void MyGreatMethod()
{
Console.WriteLine(MyArray[0] / 3);
Console.WriteLine(MyArray[1] / 3);
Console.WriteLine(MyArray[2] / 3);
}
}
You need to use new keyword when you want to set values for a specific array after the declaration:
public class Something
{
private int[] MyArray;
public Something()
{
MyArray = new int[3] { 100, 200, 300 };
}
public void MyGreatMethod()
{
Console.WriteLine(MyArray[0] / 3);
Console.WriteLine(MyArray[1] / 3);
Console.WriteLine(MyArray[2] / 3);
}
}
Related
I have a problem with the code:
namespace hello
{
public class Program
{
public static void Main(string[] args)
{
int xx = 5;
string[,] myArray = new string[1, 5];
if (xx > 4)
{
ResizeArray(ref myArray, 4, 5);
}
else
{
ResizeArray(ref myArray, 2, 5);
}
}
void ResizeArray(ref string[,] original, int rows, int cols)
{
string[,] newArray = new string[rows, cols];
Array.Copy(original, newArray, original.Length);
original = newArray;
}
}
}
I get the error message:
An object reference is required for the non-static field, method, or
property 'hello.Program.ResizeArray(ref string[,], int, int)'
Static members can't access non-static member without creating an instance.
You just need:
static void ResizeArray(ref string[,] original, int rows, int cols)
Let's say I have a text file and a line like this:
This is an example line within a file.
What I need to do is to modify this line based on a prefixed column position, and an input expectedString.
For example:
When i want to modify "example" text from the line above:
I would start from position 11 of that line as an input, and take 7 characters.
It would be something like:
TestMethod1()
{
int posStart = 11;
int posEnd = 17;
ModifyLine(line number, posStart, posEnd, expectedString)
}
I may have many similar methods with the only different is the posStart, and posEnd. I want to change it to a shorter version like this:
TestMethod1()
{
ModifyLine(line number, examplePosStart, examplePosEnd, stringExpected)
}
+examplePosStart, examplePosEnd would be declared somewhere not in the same file.
class TextPosition
{
public constant int example1PosStart = 11;
public constant int example1PosEnd = 17;
public constant int example2PosStart = 18;
public constant int example2PosStart = 25;
}
I am wondering are there any other more optimal ways to declare all the posStarts, posEnds in one place like above?
You can use an array
public class TextPosition
{
public int StartPos { get; set; }
public int EndPos { get; set; }
public static readonly TextPosition[] Positions = new[] {
new TextPosition { StartPos = 11, EndPos = 17 },
new TextPosition { StartPos = 18, EndPos = 25 }
}
}
If I call the default constructor "Creature" in main and then try to call the method "Generate Creator" the loop never runs. If I did a normal for loop it throws out of bounds errors even knowing the default constructor sets the length of the array. It is probably a dumb error I am not seeing. (this isnt all of the code)
class Creature
{
static int geneLength;
byte[] Chromosome = new byte[geneLength];
int fitness;
string geneString;
Random rn = new Random();
public Creature()
{
geneLength = 36;
fitness = 0;
}
public void GenerateCreature()
{
foreach(byte g in Chromosome)
{
Chromosome[g] = (byte)rn.Next(0, 2);
geneString += Chromosome[g].ToString();
}
}
}
Main:
namespace Creature_Generator
{
class Program
{
static void Main(string[] args)
{
Creature c = new Creature();
c.GenerateCreature();
Console.WriteLine(c.getGeneString);
}
}
}
foreach(byte g in Chromosome)
{
Chromosome[g] = (byte)rn.Next(0, 2); // 'g' is not an index
geneString += Chromosome[g].ToString(); // 'g' is not an index
}
while you are using foreach (byte g in Chromosome), I believe it is not a proper way to use code like Chromosome[g] which g is suppose a value not an index
try
StringBuilder geneString = new StringBuilder();
public Creature()
{
geneLength = 36;
this.Chromosome = new byte[geneLength];
fitness = 0;
}
for (int i = 0; i < this.Chromosome.Length; i++)
{
byte g = this.Chromosome[i]; // this line is useless
this.Chromosome[i] = (byte)rn.Next(0, 2);
geneString.Append(this.Chromosome[i].ToString());
}
Plus, if you are hard-coding geneLength = 36 in the constructor, consider use public int geneString { get; private set;} instead of static int geneLength; or
static int _geneLength = 36;
public int geneLength { get; private set; }
public Creature() { this.geneLength = _geneLength; }
public Creature(int geneLength) { this.geneLength = geneLength; }
Edit 1 -
According to #moreON advice, string geneString is modified from class string to StringBuilder, read more on https://msdn.microsoft.com/en-us/library/system.text.stringbuilder(v=vs.110).aspx
Other than your issue attempting to use the results of foreach to index an array, as others have mentioned, you're also ignoring the order in which initialisers and constructors are executed.
If we ignore inheritance (because you have none that is interesting here). Initializers are run before constructors.
This means that you are creating the array Chromosome before assigning 36 to geneLength. This means that geneLength was still default(int), which is 0, so you created an array with length 0.
For more on c# constructors see Jon Skeet's excellent page: http://jonskeet.uk/csharp/constructors.html
geneLength should probably also not be static, but that's a different discussion.
If you want geneLength to be a static field then you need to initialize it with a static constructor. Otherwise the value of geneLength is still 0 at the moment you instantiate the class.
Write your code like this instead:
class Creature
{
static int geneLength;
byte[] Chromosome = new byte[geneLength];
int fitness;
string geneString;
Random rn = new Random();
static Creature()
{
geneLength = 36;
}
public Creature()
{
fitness = 0;
}
public void GenerateCreature()
{
foreach (byte g in Chromosome)
{
Chromosome[g] = (byte)rn.Next(0, 2);
geneString += Chromosome[g].ToString();
}
}
}
So I got this base class
abstract class Item
{
private int x, y, ataque, defesa, saude, raridade;
private char appearance;
private bool pickedUp;
private readonly Random rng = new Random();
public Item(Map argMap, int argAtaque, int argDefesa, int argSaude, int argRaridade, char argAppearance)
{
bool empty = false;
while (!empty)
{
x = rng.Next(1, argMap.ReLengthX() - 1);
y = rng.Next(1, argMap.ReLengthY() - 1);
if (!argMap.CheckTile(y, x)) empty = true;
}
pickedUp = false;
ataque = argAtaque;
defesa = argDefesa;
saude = argSaude;
raridade = argRaridade;
appearance = argAppearance;
}
}
And I got this derived class
class Armadura : Item
{
public Armadura(Map argMap, int ataque, int defesa, int saude, int raridade, char appearance) : base(argMap, ataque, defesa, saude, raridade, appearance)
{
ataque = -1;
defesa = 2;
saude = 0;
raridade = ReRNG().Next(Convert.ToInt32(Math.Round(argMap.ReLengthY() * 0.02)), Convert.ToInt32(Math.Round(argMap.ReLengthY() * 0.04)));
appearance = ' ';
}
}
So my question is, how do I get to set the values on :base, using the values that I set on the derived constructor (for example, set the base argAtaque with ataquewwww, therefore, argAtaque being equal to '-1')?
I tried this using a few ways but I didn't get this to work in any way.
I thank you in advance!
The : base() syntax will work for constants and parameters, but not for more complex expressions with side-effects (as you found).
You'll be needing a initialization method on the base class.
abstract class Item
{
...
// If you use this constructor, call Setup() afterwards.
public Item() {}
// Constructor including a call to Setup()
public Item(Map argMap, int argAtaque, int argDefesa, int argSaude, int argRaridade, char argAppearance)
{
Setup(argMap, argAtaque, argDefesa, argSaude, argRaridade, argAppearance);
}
// Sets private variables for this Item
protected void Setup(Map argMap, int argAtaque, int argDefesa, int argSaude, int argRaridade, char argAppearance)
{
bool empty = false;
while (!empty)
{
x = rng.Next(1, argMap.ReLengthX() - 1);
y = rng.Next(1, argMap.ReLengthY() - 1);
if (!argMap.CheckTile(y, x)) empty = true;
}
pickedUp = false;
ataque = argAtaque;
defesa = argDefesa;
saude = argSaude;
raridade = argRaridade;
appearance = argAppearance;
}
}
Now you can setup the base class with the calculated values:
class Armadura : Item
{
public Armadura(Map argMap)
{
int ataque = -1;
int defesa = 2;
int saude = 0;
int raridade = ReRNG().Next(Convert.ToInt32(Math.Round(argMap.ReLengthY() * 0.02)), Convert.ToInt32(Math.Round(argMap.ReLengthY() * 0.04)));
char appearance = ' ';
Setup(argMap, ataque, defesa, saude, raridade, appearance);
}
All you have to do is set ataque in the child constructor, as it will override what ataque is being set to in your base class. The base constructor is called first, then the child constructor.
For this to work, you will need to make your private variables protected in the base class. This will make them private in the child class.
I'm setting up multiple methods and wondering how to continue to pass one variable (The "top" variable) to different methods.
Main method:
public static void Main(string[] args)
{
int[] anArray = new int[5];
int top = -1;
PushPeek(anArray);
then I need to pass top to:
public static void PushPeek(int[] ar)
{
if (ar[ar.Length -1] == ar.Length -1)
{
//do nothing
}
else
{
top = top + 1;
Console.WriteLine(ar[top]);
}
}\
I know it involves something with get; set; but I don't know how, any help?
Pass it by reference:
public static void PushPeek(int[] ar, ref int top)
{
...
}
int[] anArray = new int[5];
int top = -1;
PushPeek(anArray, ref top);
All about properties: http://msdn.microsoft.com/en-us/library/aa288470(v=vs.71).aspx
Auto-implemented properties are awesome! http://msdn.microsoft.com/en-us/library/bb384054.aspx