7

Consider this code:

public string Variable1 { get; set;}
public int Variable2 { get; set;}

public void Function()
{
 // Has been Variable1 Initialized?
}

Inside the function, I want to know if a value has been sent to Variable1 & Variable2, prior to the function call,

even if the DEFAULT values have been sent, that's ok (null for string & 0 for int)

Cătălin Rădoi
  • 1,804
  • 23
  • 43
  • 4
    I think the meta-answer here is "so don't do that". Make sure all variables are initialized in the constructor. – Martijn May 20 '15 at 09:02
  • What if I have two functions. F1 & F2, each using both Variables. But for F1 I must be sure that the caller of the function has set values to the variables, even if those are null. For the F2 I don't care, I don't want to force him to send something in the constructor! – Cătălin Rădoi May 20 '15 at 09:58
  • if for F1 you need the *caller* to have set the variables, why don't you just pass them as arguments to F1? – Martijn May 20 '15 at 10:02
  • It's about Clean Code, Cohesion, the fact that I use Variable1 & Variable2 for multiple other functions, but only in some parts I want to throw an exception if they haven't been initialized and so on... – Cătălin Rădoi May 20 '15 at 10:07
  • If you need Variable1 and Variable2 to be set for F1 to run, your object is in an inconsistent state if they aren't. So you have to set them before the object is ready for use. Maybe you want to decompose your object to split out the requirements? – Martijn May 20 '15 at 10:12

4 Answers4

8

Consider using a simple wrapper like this:

public struct AssignableProperty<T>
{
    private T _value;

    public T Value
    {
        get { return _value; }
        set
        {
            WasAssigned = true;
            _value = value;
        }
    }

    public bool WasAssigned { get; private set; }

    public static implicit operator AssignableProperty<T>(T data)
    {
        return new AssignableProperty<T>() { Value = data };
    }

    public static bool operator ==(AssignableProperty<T> initial, T data)
    {
        return initial.Value.Equals(data);
    }

    public static bool operator !=(AssignableProperty<T> initial, T data)
    {
        return !initial.Value.Equals(data);
    }

    public override string ToString()
    {
        return Value.ToString();
    }
}

Then your class'll look like this:

public class Test
{
    public AssignableProperty<string> Variable1 { get; set; }
    public AssignableProperty<int> Variable2 { get; set; }

    public void Function()
    {
        if(Variable1.WasAssigned&&Variable2.WasAssigned)
            //do stuff
    }
}

You can go further and add throw Exception or contract to getter, so if somebody'll try to access uninitialized value it'll throw an exception or show you warning

Alex Voskresenskiy
  • 2,143
  • 2
  • 20
  • 29
2

Some basics about default value in C#:

When an instance of a class (or struct) is created, all fields are initialized to their respective default value.

For reference types, it will be null. For value types, it will be equivalent to 0. This is easily explains as the memory management ensures that new allocated memory is initialized to 0x0 bytes.

Auto-properties hide the generated field, but there is one. So the same rules apply.

Now to answer your question, the best way to make sure that values are initialized is to make a constructor with one parameter for each field/property and to hide the default constructor with no parameters:

public Yourtype(String param1, Int32 param2)
{
    this.Variable1 = param1;
    this.Variable2 = param2;
}

private Yourtype() { }

Other alternatives is described in @Sean and @Alex answers if only a subset of properties/fields needs to be initialized/checked. But this hides some overhead (one bool for each property/field and some indirection).

Kryptos
  • 875
  • 8
  • 19
0

For the reference types you'll need to add a flag:

string m_Variable1;
bool m_IsVariable1Set;

public string Variable1
{
  get{return m_Variable1;}
  set{m_IsVariable1Set = true; m_Variable1 = value;}
}

For the value types you can use a nullable value

int? m_Variable2;

int Variable2
{
  get{return m_Variable2.GetValueOrDefault();}
  set{m_Variable2 = value;}
}

Which you can then check to see if it's been set by using m_Variable2.HasValue.

Sean
  • 60,939
  • 11
  • 97
  • 136
-2

Well you can simply do a check on both variables to see if they have any value assigned to them in your function

public void Function()
{

    if (String.IsNullOrEmpty(Variable1) && Variable2 ==0 )
    {
      // Variables are not assigned
    }

}
Charles
  • 67
  • 8
  • 1
    And if `Variable1` is `null`, does that mean someone initialized the value or not? – Yuval Itzchakov May 20 '15 at 08:53
  • If you want to check for a default value of a Type at runtime you should use: http://stackoverflow.com/questions/1281161/how-to-get-the-default-value-of-a-type-if-the-type-is-only-known-as-system-type – Noel Widmer May 20 '15 at 08:58
  • I don't want to check for a default value. I want to check if prior to the function call, someone has sent something to the var, even if that's NULL or zero or whatever default value for each type. – Cătălin Rădoi May 20 '15 at 09:37