How to use get and set for array element in C#? - c#

I have the following class:
public class test
{
private int i;
public test(int in)
{
i = in;
}
public int testint;
{
get { return i; }
set { i = testint; }
}
}
And the following code:
test[] data = new test[3];
for(int j = 0; j < 3; j++)
{
data[i] = new test(0);
data[i].testint = int.Parse(Console.ReadLine());
}
Console.WriteLine(test[0].testint);
Console.WriteLine(test[1].testint);
Console.WriteLine(test[2].testint);
When I run this program and type in 1, 2, 3 as the input, the output is 0, 0, 0. I don't understand why the get or set seem to be not working. If I initialize the array elements with a value other than 0, the output will be that. The data[i].testint = int.Parse(Console.ReadLine()); seems to not be working. How would I go about doing something like that?

Change the set method to this:
public int testint
{
get { return i; }
set { i = value; }
}

You setter is incorrect. It should be:
set { i = value; }
You had:
set { i = testint; }
Which only triggers the getter, which gets from i, so in the end your setter was doing i = i .
In a setter, the value keyword contains the new candidate value for the property. value's type equals the property's. I say candidate value because you can validate it and choose to not apply it.
In your case, you were not applying the value.
Update
Also, when defining getters and setters, no semicolon should be used. Code, then, would look like this:
public int testint
{
get { return i; }
set { i = value; }
}

I see two errors in this code:
public int testint;
{
get { return i; }
set { i = testint; }
}
There should be no semicolon after testint at the top. Also, set needs to assign using value, like this:
public int testint
{
get { return i; }
set { i = value; }
}

Change your setter to say:
set { i = value; }
value corresponds to the value you send to set the variable.

Here's simple way.
public int TestInt {get; set;}

Related

How to set the Value variable of this custom Odin Inspector class

I know, the title is bad, but I couldn't think if a better one. The question is very specific.
Ok, so I'm using a class in my game identical to Odin Inspector's example RPG Skills classes. But it's set up in a way I don't quite understand and I can't work out how to set the value (I can get it, and there is a setter, so it's possible to set too). Also, all the skill classes/structs/etc are in the same .cs file.
The SkillList function I use to get the Value:
(I get it with skills[Strength].Value; in other classes)
public int this[SkillType type]
{
get
{
for (int i = 0; i < this.skills.Count; i++)
{
if (this.skills[i].Type == type)
return this.skills[i].Value;
}
return 0;
}
set
{
for (int i = 0; i < this.skills.Count; i++)
{
if (this.skills[i].Type == type)
{
var val = this.skills[i];
val.Value = value;
this.skills[i] = val;
return;
}
}
this.skills.Add(new SkillValue(type, value));
}
}
SkillValue struct:
[Serializable]
public struct SkillValue : IEquatable<SkillValue>
{
public SkillType Type;
public int Value;
public SkillValue(SkillType type, int value)
{
this.Type = type;
this.Value = value;
}
public SkillValue(SkillType type)
{
this.Type = type;
this.Value = 0;
}
public bool Equals(SkillValue other)
{ return this.Type == other.Type && this.Value == other.Value; }
}
SkillType enum:
public enum SkillType
{
Science,
Technology,
Arts,
Language,
}
I've tried:
skills[Science].Value = 10;
skills[Science] = new SkillValue(Science, 10);
skills[Science, 10]; (using a new function made by me)
skills[Science](10);
skills[Science].Value(10);
skills[Science] = 10;
But none work, and I'm just guessing randomly now.
How can I set the value?
Thanks
The solution:
character.skills[Rorschach.Character.Skills.SkillType.Science] = value;
Your property is of type int and expects a key of type SkillType so it should probably be
SkillList skills;
skills[SkillType.Science] = 10;
actually also
I get it with skills[Strength].Value;
seems odd with the code you provided. As said the property returns an int which has no property Value so it should actually be
int x = skills[SkillType.Strength];
Now knowing the full implementation code and your actual usage:
public SkillList skills;
...
public int Science
{
get { return this.Character.skills[Science].Value; }
set { this.Character.skills[Science].Value(10); }
}
ATTENTION!
What you did here by accident is using the other property
public SkillValue this[int index]
{
get { return this.skills[index]; }
set { this.skills[index] = value; }
}
which takes an int index and returns a SkillValue.
BUT you are causing a runtime StackOverlowExeption due to a recursive call of Science.
You can't use Science inside of the getter or setter of equally called property!
Imagine using the getter as example:
You would call
var test = Science;
so it executes the getter
return Character.skills[Science].Value;
but well ... in order to know the value of Science in order to use it here as the index it would again have to execute the getter so again
return Character.skills[Science].Value;
and by now you hopefully get what I mean.
Solution
You property should actually as guessed before rather look like
public int Science
{
get { return Character.skills[SkillType.Science]; }
set { Character.skills[SkillType.Science] = value; }
}

Why can only auto-implemented properties can have initializers in C#?

I get the "only auto-implemented properties can have initializers in C#" error when trying to do the following:
public int Precision
{
get { return Precision; }
set
{
if (value < 0)
Precision = 0;
else if (value > 15)
Precision = 15;
else
Precision = value;
}
} = 12;
Why is this not allowed?
Pretty sure that is not really how you use get and set. Plus your get suffers from self reference. I think this is what you want:
private int _precision = 12;
public int Precision {
get => _precision;
set {
if (value < 0)
_precision = 0;
else if (value > 15)
_precision = 15;
else
_precision = value;
}
}
Well, an auto-property is just syntactic sugar for a property that gets and sets an automatically created backing-field. So the following two code-segments are similar:
public int Precision { get; set; }
and
public int Precision
{
get { return <Precision>k__BackingField; }
set { <Precision>k__BackingField = value; }
}
However when you create some own logic within your property, thereĀ“s no such thing as an automatically backing-field. In fact you could even do the following without any backing-field:
set { Console.WriteLine(); }
An initial value however is resolved to the following constructor:
MyClass()
{
this.<Precision>k__BackingField = myValue;
}
However when there is no such backing-field, what should the compiler do here?

Null Reference Exception was unhandled C# console application

I know this is probably similar to some other posts, but I'm not quite sure what I'm doing wrong here. As an FYI, I'm new to programming and still trying to learn proper flow.
Here is the code, the exception occurs at "MyFriends[i].Name = friendName".
using System;
using System.Collections;
namespace FriendList
{
class FriendList
{
static public Friend[] MyFriends = new Friend[2];
public static void Main()
{
string friendName;
string friendPhone, friendMonth, friendDay, friendYear;
int intMonth, intDay, intYear;
for (int i = 0; i < 2; ++i)
{
Console.Write("enter name");
friendName = Console.ReadLine();
MyFriends[i].Name = friendName;
Console.Write("phone");
friendPhone = Console.ReadLine();
MyFriends[i].Phone = friendPhone;
Console.WriteLine("Enter Month: ");
friendMonth = Console.ReadLine();
intMonth = Convert.ToInt32(friendMonth);
MyFriends[i].Month = intMonth;
Console.WriteLine("Enter Day: ");
friendDay = Console.ReadLine();
intDay = Convert.ToInt32(friendDay);
MyFriends[i].Day = intDay;
Console.WriteLine("Entery Year: ");
friendYear = Console.ReadLine();
intYear = Convert.ToInt32(friendYear);
MyFriends[i].Year = intYear;
}
for (int i = 0; i < 2; ++i)
{
string information = string.Format("first name: {0}, phone {1}", MyFriends[i].Name, MyFriends[i].Phone);
Console.WriteLine(information);
}
Console.Read();
}
}
class Friend
{
string _Name = string.Empty, _Phone = string.Empty;
int _Day = 0, _Month = 0, _Year = 0;
public string Name
{
get { return _Name; }
set { _Name = value; }
}
public string Phone
{
get { return _Phone; }
set { _Phone = value; }
}
public int Month
{
get { return _Month; }
set { _Month = value; }
}
public int Day
{
get{ return _Day; }
set{ _Day = value ; }
}
public int Year
{
get { return _Year;}
set { _Year = value; }
}
public Friend()
{ }
}
}
Thank you for your guidance!
Your friend array is initialized empty. So MyFriends[i] will hit a null reference, which is another way to say you are trying to access something that doesn't exist.
In other words, you have an Array with slots for two friends, but both slots are empty. You still need to have a friend in each slot before you can use their properties, such as Name, Phone etc.
Simply start the for loop like this:
for (int i = 0; i < 2; ++i)
{
MyFriend[i] = new Friend(); //or pass parameters as required by the constructor
// rest of your code goes here
}
And things will be fine. This way, you are adding a friend to the slot you will be using.
You've created an array with two elements, but you have set the elements to any value. They are both null:
static public Friend[] MyFriends = new Friend[2];
So, when you try to use MyFriends[i] from the array, you're actually getting null.
MyFriends[i].Name = friendName;
That where your NullReferenceException came from.
You'll have to initialize the members of the array. For example:
for (int i = 0; i < MyFriends.Length; i++)
{
// Put a new Friend object in the array.
MyFriends[i] = new Friend();
// ...
When creating collections, they're populated with default values of the target type, and the default value for any reference type if null. So to solve your problem you'd have to initialize items in the array before accessing them:
....
for (int i = 0; i < 2; ++i)
{
MyFriends[i] = new Friend();
...
MyFriends is an array of Friend class.
each element in the array needs to be initialized with a friend constructor so it will be allocated with a memory.

Populate ObjectListView using a List

I'm trying to populate a DataTreeListView from ObjectListView library using a list. Unfortunately I am unable to achieve it, there is nothing displayed even though there is a count of item inside the List itself.
Class.cs
public class Class
{
protected string xName;
protected int xId;
protected int xParentId;
protected int happinessStatus;
protected int salaryStatus;
public Class()
{
this.xName = "";
this.xId = 0;
this.xParentId = 0;
this.happinessStatus = 0;
this.salaryStatus = 0;
}
public String Name
{
get { return this.xName; }
set { this.xName = value; }
}
public int Id
{
get { return this.xId; }
set { this.xId = value; }
}
public int ParentId
{
get { return this.xParentId; }
set { this.xParentId = value; }
}
public int HappinessStatus
{
get {return this.happinessStatus; }
set { this.happinessStatus = value; }
}
public int SalaryStatus
{
get { return this.salaryStatus; }
set { this.salaryStatus = value; }
}
public static List<Class> GetList()
{
List<Class> oList = new List<Class>();
Class oClass = new Class();
oClass.Name = "Person A";
oClass.Id = 1;
oClass.ParentId = 0;
oClass.HappinessStatus = 1;
oClass.SalaryStatus = 1000;
oList.Add(oClass);
oClass.Name = "Person B";
oClass.Id = 2;
oClass.ParentId = 1;
oClass.HappinessStatus = 1;
oClass.SalaryStatus = 2000;
oList.Add(oClass);
oClass.Name = "Person C";
oClass.Id = 3;
oClass.ParentId = 1;
oClass.HappinessStatus = 1;
oClass.SalaryStatus = 1000;
oList.Add(oClass);
return oList;
}
On the MainForm's Load Event,
I did the following:
List<Class> list = new List<Class>();
list = Class.GetList();
dataTreeListView1.DataSource = list;
On the designer view, I've also created columns which has got aspect name set to each of the property of the class file except the Id and ParentId.
KeyAspectName : Id
ParentKeyAspectName: ParentId
I did a small messagebox to show the count of the item in the list, its correct but nothing displayed out on the dataTreeListView control.
May I know what is wrong with my coding?
Did you set KeyAspectName, ParentKeyAspectName and RootKeyValue accordingly?
If you did it using the designer, RootKeyValue may be your problem:
Due to the limitations of the Designer in the IDE, RootKeyValue can only be given a string value through the IDE. If your ParentKey is not of type string, you will have to set its value through code.
Since you parent key is of type int use
dataTreeListView1.RootKeyValue = 0;
Note that in contrast to the basic OLV, you don't need to add columns manually. If you want to hide the key columns set ShowKeyColumns = false.
EDIT:
There is another mistake in you code. You add the same instance of the object oClass 3 times. Use oClass = new Class(); before initializing a new person.

C# StackOverflowException

Problem: I am trying to update a List. If a certain item's ID already exists in the List, I want to add onto that item's quantity. If not, then I want to add another item to the list.
cart = (List<OrderItem>)Session["cart"];
for(int counter = cart.Count-1; counter >= 0; counter--)
{
if (cart[counter].productId == item.productId)
{
cart[counter].productQuantity += item.productQuantity;
}
else if (counter == 0)
{
cart.Add(item);
}
}
cart[counter] and item represent an instance(s) of a custom object of mine. Currently when I finally find a matching ID, everything APPEARS as though it should work, but I get a StackOverflowException thrown in my custom object class.
public int productQuantity
{
get
{
return _productQuantity;
}
set
{
productQuantity = value;
}
}
It gets thrown right at the open-bracket of the "set". Could somebody please tell me what the heck is wrong because I've been going at this for the past 2+ hours to no avail. Thank you in advance.
the problem is in your setter of the productQuantity
it should read:
set
{
_productQuantity= value;
}
edit (naming convention):
public class Vertex3d
{
//fields are all declared private, which is a good practice in general
private int _x;
//The properties are declared public, but could also be private, protected, or protected internal, as desired.
public int X
{
get { return _x; }
set { _x = value; }
}
}
Replace productQuantity = value; with _productQuantity = value; (you're recurring infinitely by calling the setter over and over)
Why not just use this instead?
public int productQuantity { get; set; }
But the flaw was in the _
public int productQuantity {
get {
return _productQuantity;
}
set {
_productQuantity = value;
}
}
cart = (List<OrderItem>)Session["cart"];
int index = cart.Find(OrderItem => OrderItem.productId == item.productId);
if(index == -1) {
cart.Add(item);
} else {
cart[index].productQuantity += item.productQuantity;
}
public int productQuantity
{
get
{
return _productQuantity;
}
set
{
_productQuantity = value; //this should be an assignment to a member variable.
}
}

Categories

Resources