2

I have a struct on the server-side with a layout like this:

struct SomeStruct
{
    public string SomeString { get; set; };
    public string SomeString1;
    public string SomeString2;
    public string SomeString3;
}

I am using a client/server model, and an instance of this struct gets referenced a lot of times as it has really important information (over 200 times).

The thing is that when some function gets called, the values inside this struct become null. I don't know why and it is been bugging me for a really long time.

I call a lot of methods before realizing that this values are null, so I don't know which section of my code nullify my strings.

I am using VS2012, but I have 2010 and 2008 ultimate as well. I was wondering if there is a way to perform a trigger when some section of code nullifies my strings.

I tried to add some properties like this, bot the exception was never thrown:

struct SomeStruct {
    string somestr;
    public string SomeString
    {
        get { return somestr; }
        set
        {
            if (value == null)
            {
                throw new Exception("stirng is null");
            }

            somestr = value;
        }
    }
    public string SomeString1;
    public string SomeString2;
    public string SomeString3;
}

Might not be important, but this is one of the structs I am using (the Name variable becomes null in some part of my code, and the rest turns into default()):

[ProtoContract]
public struct CharacterInformation
{
    [ProtoMember(2)]
    public string Name;
    [ProtoMember(3)]
    public IntegerVector2 Position;
    [ProtoMember(5)]
    public CharacterDirection Direction;
    [ProtoMember(6)]
    public CharacterStatus Status;
    [ProtoMember(7)]
    public CharacterClass Class;
    [ProtoMember(8)]
    public CharacterRace Race;
    [ProtoMember(9)]
    public CharacterType Type;
    [ProtoMember(10)]
    public CharacterFaction Faction;
    [ProtoMember(11)]
    public float MovementModifier;
    [ProtoMember(12)]
    public CharacterEquipment Equipment;
}

Edit: The only instance of this struct is created on a Sql-related function:

public CharacterServerInformation GetInformation(int charID)
        {
            CharacterServerInformation information = new CharacterServerInformation();
            if (!authInstance.CharacterExists(charID))
            {
                // char doesn't exists
                throw new Exception("Character doesn't exists");
            }
            information.ID = charID;
            information.Experience = GetExperience(charID);
            information.Info.Direction = CharacterDirection.Bottom;
            information.Info.Name = authInstance.CharacterGetName(charID);
            information.Info.Class = GetClass(charID);
            information.Info.Faction = GetFaction(charID);
            information.Info.Position = GetPosition(charID);
            information.Info.Race = GetRace(charID);
            information.Info.Status = GetStatus(charID);
            information.Info.Type = GetType(charID);
            information.Info.MovementModifier = 1f; // should store old movement modifier, but well, whatever
            information.HealthLeft = GetHealthLastLogout(charID);
            return information;
        }
Pacha
  • 1,438
  • 3
  • 23
  • 46
  • Can you show how you are creating and using instances of the struct? – hatchet - done with SOverflow Oct 05 '12 at 23:24
  • Simple debug version: throw `ArgumentException` if something happens to set it to null? I haven't done much with C# (yet), but isn't modifying internal struct values recommended against? – Clockwork-Muse Oct 05 '12 at 23:24
  • @Clockwork-Muse - yes..OP should read this http://stackoverflow.com/questions/441309/why-are-mutable-structs-evil – hatchet - done with SOverflow Oct 05 '12 at 23:27
  • Should I change all my structs to classes? If they have mutable data* – Pacha Oct 05 '12 at 23:30
  • @Pacha - this http://stackoverflow.com/questions/521298/when-to-use-struct-in-c may help answer your question about struct vs. class. – hatchet - done with SOverflow Oct 05 '12 at 23:33
  • @Pacha I think so. For performance issues and bug-prevention (since structs are passed by value not by reference) –  Oct 05 '12 at 23:35
  • You might be right. I am really new to programming, I still make silly mistakes. Didn't know about this. I thought that structs should contain data and classes functionality. – Pacha Oct 05 '12 at 23:36
  • Putting code to notify if a setter is called with a null value might not help. The struct may be getting nullified because you're assigning `_s = new SomeStruct();` somewhere by mistake. The property setters won't get called here, but the underlying fields will be null. – phoog Oct 05 '12 at 23:38

1 Answers1

4

I suspect the problem is purely because you're using struct and not making a class. Since struct members are copied by value into methods and when returned from methods, including property getters, it's likely that you're "losing" the information by accidentally writing a new struct somewhere.

In this case, class seems is far more appropriate. If you read Choosing Between Classes and Structures, you'll see that struct should only be used when:

  • It logically represents a single value, similar to primitive types (integer, double, and so on).
  • It has an instance size smaller than 16 bytes.
  • It is immutable.
  • It will not have to be boxed frequently.

In your case, all of these criteria ( except maybe the last) are being violated, so class would be more appropriate.

Reed Copsey
  • 554,122
  • 78
  • 1,158
  • 1,373