Why i can't modify these values in an object? - c#

I have a problem, if i want to edit a value into an object and call it again, i get the old value instead of the new one.
Here is my Function to get the Class:
public static Clan GetClanByID(int Index)
{
foreach (Clan Clan in Clans)
{
if (Clan.ID == Index)
{
return Clan;
}
}
return new Clan()
{
ID = -1,
Name = "NULL",
IconID = -1
};
}
Here is my function to update the Value:
public static void ChangeAnnouncement(int ClanID, int Mode, string Text)
{
if (ClanID != -1)
{
Clan Clan = GetClanByID(ClanID);
if (Mode == 0)
{
Clan.Description = Text;
}
else if (Mode == 1)
{
Clan.News = Text;
}
}
}
And here is the class:
public class Clan
{
public int ID;
public int LeaderID;
public int Extension;
public int CreationDate;
public long EXP;
public long IconID;
public string Name;
public string News;
public string Description;
public List<ClanWars> ClanWars;
public List<ClanUsers> Users;
public List<ClanCoMasters> CoMasters;
public List<ClanPendingUsers> PendingUsers;
public LeaderInformations LeaderInformations;
}
Example: The old value was "123", than i call the function ChangeAnnouncement, and set the value to "1234567890", after that i get the value using GetClanByID(ID).Description, but i will still get the old value ("123")
I Hope you can help me.

You're returning a new Clan every time. You forgot adding the newly created clan to Clans.

Related

How to remove items from listbox

i tried to remove item from listbox using MultiExtended as selection mode
this is my code
im using this snippet code for getid from listbox
private int getid(int index)
{
int.TryParse(lb_ItemList.Items[lb_ItemList.SelectedIndices[index]].ToString().Split('-')[0], out index);
return index;
}
and this code im using for remove index from listbox
for (int i = lb_ItemList.Items.Count - 1; i > -1; i--)
{
lb_ItemList.Items.RemoveAt(lb_ItemList.SelectedIndices[getid(i)]);
}
but for any reason it doesn't work... any suggestion? thanks
I assume you need to copy the content of lb_ItemList.SelectedIndices before you start remove items out of lb_ItemList because every call to Remove(...) will update the content of lb_ItemList.SelectedIndices
You only need remove by index and SelectedIndices has the index:
for (int i = lb_ItemList.SelectedIndices.Count - 1; i > -1; i--)
{
var index = lb_ItemList.SelectedIndices[i];
lb_ItemList.Items.RemoveAt(index);
}
You don't need your Id to remove selected items.
If you need work with you class in the Items, I recomended you create an Item class:
public class YourItem
{
public YourItem()
{
}
public YourItem(int id, string name)
{
this.Id = id;
this.Name = name;
}
public int Id { get; set; }
public string Name { get; set; }
public override string ToString()
{
return $"{this.Id} - {this.Name}";
}
}
Then, you add your items to the ListBox:
this.lb_ItemList.Items.Add(new YourItem(1, "A"));
this.lb_ItemList.Items.Add(new YourItem(2, "B"));
this.lb_ItemList.Items.Add(new YourItem(3, "C"));
this.lb_ItemList.Items.Add(new YourItem(4, "D"));
The text of each item is that you return in ToString method of YourItem. For example "1 - A" for the first item.
And, when you are working with the ListBox, simply cast to your class:
var item = (YourItem)this.lb_ItemList.Items[1];
var id = item.Id;
var name = item.Name;
If you class is big, you can use your Item as a wrapper:
public class YourClass
{
public int Id { get; set; }
public string Name { get; set; }
// Other properties, methods...
}
public class YourItem
{
private YourClass _item;
public YourItem(YourClass obj)
{
this._item = obj;
}
public int Id
{
get { return this._item.Id}
set { this._item.Id = value; }
}
public string Name
{
get { return this._item.Name}
set { this._item.Name = value; }
}
public override string ToString()
{
return $"{this.Id} - {this.Name}";
}
}
Your class maybe have lost of information but for your item, you only expose Id and Name, for example.

C# - Detect when string is beyond [MaxLength(#)] and truncate?

I have a object class like so:
public class MyObject
{
[MaxLength(128)]
public string Name {get; set;}
}
However, when I make MyObject with a string for Name of more than 128 characters, I can set it and it works. This causes issues down the line because when I go to insert this object into the database, it exceptions due to the string being to long for that column in the table.
How would I go about making sure that a string that is too long gets truncated? And how can I detect when that happens so I can log it?
In the setter you can add some validation.
public class MyObject
{
private string name;
public string Name
{
get
{
return name;
}
set
{
if (string.IsNullOrEmpty(value) || value.Length <= 128)
{
name = value;
}
else
{
//log? do something or truncate
name = value.Substring(0, 127);
}
}
}
}
Alternatively I don't like it but I tried to make it work with an Attribute and made it easier to scale with a helper class.
public class MyObject
{
private string name;
[MaxLength(128, ErrorMessage = "String is longer than {1} characters and has been truncated.")]
public string Name
{
get { return name; }
set
{
name = value.Validate(GetType().GetProperty(MethodBase.GetCurrentMethod().Name.Substring(4)).GetCustomAttributes(false));
}
}
}
public static class Tools
{
public static string Validate(this string value, object[] attributes)
{
if (attributes.FirstOrDefault(x => x is MaxLengthAttribute) is MaxLengthAttribute maxLengthAttribute)
{
if (maxLengthAttribute.IsValid(value))
{
return value;
}
else
{
//LogMethod(maxLengthAttribute.FormatErrorMessage(maxLengthAttribute.MaximumLength.ToString()));
return value.Substring(0, maxLengthAttribute.Length - 1);
}
}
return value;
}
}

Using implicit operator overloading

I created the following struct to keep track of all my network IDs I use for my game:
public struct NetworkId {
private static int _availibleId = 1;
private int _id;
public static implicit operator int(NetworkId i) {
if (i._id == 0) {
i._id = _availibleId++;
}
return i._id;
}
}
I initialize the ID at the moment someone tries to access it. But my problem now is, when I use the id like in the following example, the ID gets reassigned every time.
public class TestObject {
private NetworkId _id;
public NetworkId Id { get { return _id; } }
public void Create {
NetworkManager.SendPacket(new Packets.CreateObject(Id));
}
}
I can't wrap my head around what is happening here. Thank you for your help!
Does it need to be a struct? With class semantics do this:
public class NetworkId
{
private static int _availibleId = 1;
public int Id { get; } = _availibleId++;
public static implicit operator int(NetworkId i)
{
return i.Id;
}
}
void Test() {
int A = new NetworkId(); //A=1
int B = new NetworkId(); //B=2
}

Hash set - unique items not added

I have a class that contains the following:
HashSet<CookieSetItem> _set = new HashSet<CookieSetItem>();
public IEnumerable<CookieSetItem> Set
{
get { return _set; }
}
public void Add(int id)
{
id.ThrowDefault("id");
var item = new CookieSetItem(id);
if (_set.Add(item))
{
// this only happens for the first call
base.Add();
}
}
When I call the add method multiple times, say with ID's 1,2,3 etc, only the first item is added.
Obviously I'm confused as a new CookieSetItem is being created each time with a unique element (the ID), so why is it not being added?.
For completeness, here's the cookie set class:
public sealed class CookieSetItem
{
readonly DateTime _added;
readonly int _id;
public DateTime Added
{
get { return _added; }
}
public int ID
{
get { return _id; }
}
public CookieSetItem(int id)
: this(id, DateTime.Now)
{
}
public CookieSetItem(int id, DateTime added)
{
id.ThrowDefault("id");
added.ThrowDefault("added");
_id = id;
_added = added;
}
}
Got to the bottom of it - more than one error, which clouded the overall view.
Firstly I updated my class with IEquatable, which fixed the adding problem. Secondly, I found that the end result which was to update a cookie with a string version of the hashset also failed due to the fact that it was not encrypted. Here's the amended class that fixed the original problem.
public sealed class DatedSet : IEquatable<DatedSet>
{
readonly DateTime _added;
readonly int _id;
public DateTime Added
{
get { return _added; }
}
public int ID
{
get { return _id; }
}
public DatedSet(int id)
: this(id, DateTime.Now)
{
}
public DatedSet(int id, DateTime added)
{
id.ThrowDefault("id");
added.ThrowDefault("added");
_id = id;
_added = added;
}
public bool Equals(DatedSet other)
{
if (other == null) return false;
return this.ID == other.ID;
}
public override bool Equals(Object obj)
{
if (obj == null) return false;
var ds = obj as DatedSet;
return ds == null ? false : Equals(ds);
}
public override int GetHashCode()
{
return ID.GetHashCode();
}
}
Thanks for the advice.

How to convert DataTable to List<T> while watching for nulls

Movie Class
public class Movie
{
#region Properties
public string Name { get { return _name; } set { _name = value; } }
public string Producer { get { return _producer; } set { _producer = value; } }
public int Rating { get { return _rating; } }
public Image Covor { get; set; }
public string Description { get { return _description; } }
public int ReleaseYear { get { return _releaseYear; } set { _releaseYear = value; }}
#endregion
#region Private Fields
private string _name;
private string _producer;
private int _rating;
private string _description;
private int _releaseYear;
#endregion
#region Constructors
public Movie()
{
}
public Movie(string name, int yearRelease)
{
this._name = name;
this._releaseYear = yearRelease;
}
public Movie(string name, int yearRelease, string producer)
{
this._name = name;
this._releaseYear = yearRelease;
this._producer = producer;
}
#endregion
}
My attempt
foreach (DataRow movieRow in MovieTable().AsEnumerable())
{
if (movieRow["Producer"] != DBNull.Value)
{
Movie movie = new Movie()
{
Name = (string)movieRow["Name"],
Producer = (string)movieRow["Producer"],
ReleaseYear = (int)movieRow["Release Year"]
};
movieList.Add(movie);
}
else
{
Movie movie = new Movie()
{
Name = (string)movieRow["Name"],
ReleaseYear = (int)movieRow["Release Year"]
};
movieList.Add(movie);
}
}
This is my code so far I'm trying to convert a Table to a List. The only problem is DBNull's.
I would like to update the entire table to a list, this works currently for 2 situations, but I need for the List to contain all the information if it exists. I could create elseif statements to handle every possible scenario but there has to be a way better way to figure out if the type is DBNull and if not set the property correctly.
If there's any confusion tell me what it is and I'll explain further.
One option is to incorporate the null-check into the set-statements wherever you need them, using shorthand code:
Name = (movieRow["Name"] == DBNull.Value) ?
(string)movieRow["Name"] :
string.Empty,
// Producer will be given a value if it exists, or null otherwise:
Producer = (movieRow["Producer"] == DBNull.Value) ?
(string) movieRow["Producer"] :
null,
...
You can replace string.Empty with null or vice versa of course, if that suits you better.
Edit: Just a very basic clarification, since you state you are new to programming: This shorthand notation means "if firstValue is true, return secondValue, otherwise, return thirdValue"
var result = firstValue ? secondValue : thirdValue;
One option: you can check IsNull(column):
Movie movie = new Movie()
{
Name = movieRow.IsNull("Name")
? (string)null : (string)movieRow["Name"],
Producer = movieRow.IsNull("Producer")
? (string)null : (string)movieRow["Producer"],
// etc..
};
movieList.Add(movie);

Categories