确保变量初始化 C#
Ensure Variable Initialization C#
考虑这段代码:
public string Variable1 { get; set;}
public int Variable2 { get; set;}
public void Function()
{
// Has been Variable1 Initialized?
}
在函数内部,我想知道在函数调用之前是否已将值发送到 Variable1 和 Variable2,
即使发送了默认值,也没关系(字符串为空,整数为 0)
关于 C# 默认值的一些基础知识:
创建 class(或结构)的实例时,所有字段都被初始化为其各自的默认值。
对于引用类型,它将是 null
。对于值类型,它将等同于 0
。这很容易解释,因为内存管理确保新分配的内存被初始化为 0x0 字节。
自动属性隐藏生成的字段,但是有一个。所以同样的规则适用。
现在回答你的问题,确保值被初始化的最好方法是为每个 field/property 创建一个带有一个参数的构造函数,并隐藏没有参数的默认构造函数:
public Yourtype(String param1, Int32 param2)
{
this.Variable1 = param1;
this.Variable2 = param2;
}
private Yourtype() { }
如果只有 properties/fields 的一个子集需要 initialized/checked,@Sean 和 @Alex 的回答中描述了其他替代方案。但这隐藏了一些开销(每个 property/field 一个 bool
和一些间接)。
考虑使用像这样的简单包装器:
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();
}
}
那么您的 class 将如下所示:
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
}
}
您可以更进一步,将 throw Exception 或 contract 添加到 getter,这样如果有人尝试访问未初始化的值,它会抛出异常或向您显示警告
好吧,您可以简单地检查两个变量,看看它们是否在您的函数中分配了任何值
public void Function()
{
if (String.IsNullOrEmpty(Variable1) && Variable2 ==0 )
{
// Variables are not assigned
}
}
对于引用类型,您需要添加一个标志:
string m_Variable1;
bool m_IsVariable1Set;
public string Variable1
{
get{return m_Variable1;}
set{m_IsVariable1Set = true; m_Variable1 = value;}
}
对于值类型,您可以使用可为 null 的值
int? m_Variable2;
int Variable2
{
get{return m_Variable2.GetValueOrDefault();}
set{m_Variable2 = value;}
}
然后您可以检查它是否已使用 m_Variable2.HasValue
设置。
考虑这段代码:
public string Variable1 { get; set;}
public int Variable2 { get; set;}
public void Function()
{
// Has been Variable1 Initialized?
}
在函数内部,我想知道在函数调用之前是否已将值发送到 Variable1 和 Variable2,
即使发送了默认值,也没关系(字符串为空,整数为 0)
关于 C# 默认值的一些基础知识:
创建 class(或结构)的实例时,所有字段都被初始化为其各自的默认值。
对于引用类型,它将是 null
。对于值类型,它将等同于 0
。这很容易解释,因为内存管理确保新分配的内存被初始化为 0x0 字节。
自动属性隐藏生成的字段,但是有一个。所以同样的规则适用。
现在回答你的问题,确保值被初始化的最好方法是为每个 field/property 创建一个带有一个参数的构造函数,并隐藏没有参数的默认构造函数:
public Yourtype(String param1, Int32 param2)
{
this.Variable1 = param1;
this.Variable2 = param2;
}
private Yourtype() { }
如果只有 properties/fields 的一个子集需要 initialized/checked,@Sean 和 @Alex 的回答中描述了其他替代方案。但这隐藏了一些开销(每个 property/field 一个 bool
和一些间接)。
考虑使用像这样的简单包装器:
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();
}
}
那么您的 class 将如下所示:
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
}
}
您可以更进一步,将 throw Exception 或 contract 添加到 getter,这样如果有人尝试访问未初始化的值,它会抛出异常或向您显示警告
好吧,您可以简单地检查两个变量,看看它们是否在您的函数中分配了任何值
public void Function()
{
if (String.IsNullOrEmpty(Variable1) && Variable2 ==0 )
{
// Variables are not assigned
}
}
对于引用类型,您需要添加一个标志:
string m_Variable1;
bool m_IsVariable1Set;
public string Variable1
{
get{return m_Variable1;}
set{m_IsVariable1Set = true; m_Variable1 = value;}
}
对于值类型,您可以使用可为 null 的值
int? m_Variable2;
int Variable2
{
get{return m_Variable2.GetValueOrDefault();}
set{m_Variable2 = value;}
}
然后您可以检查它是否已使用 m_Variable2.HasValue
设置。