C# 用于检索';默认值';价值
根据下面的示例,我正在讨论如何确定对象的默认值: 此特定扩展方法是为System.Type创建的。我试图做到的是让它更通用,我可以做这样的事情:C# 用于检索';默认值';价值,c#,generics,extension-methods,C#,Generics,Extension Methods,根据下面的示例,我正在讨论如何确定对象的默认值: 此特定扩展方法是为System.Type创建的。我试图做到的是让它更通用,我可以做这样的事情: int i = 3; bool amIaDefaultValue = i.IsDefaultValue(); 如果I==0(int的默认值),我希望返回true,对于所有其他实例,返回false 以下是我的初步尝试: public static bool IsDefaultValue<T>(this T value) { var
int i = 3;
bool amIaDefaultValue = i.IsDefaultValue();
如果I==0(int的默认值),我希望返回true,对于所有其他实例,返回false
以下是我的初步尝试:
public static bool IsDefaultValue<T>(this T value)
{
var t = typeof(T); // always comes back as object..?
if (t.IsValueType && Nullable.GetUnderlyingType(t) == null)
{
return value.Equals(Activator.CreateInstance<T>());
}
else
{
var defaultValue = default(T);
if (value == null)
return defaultValue == null;
else
return value.Equals(defaultValue);
}
}
但是如果值恰好为null,我会立即得到一个错误。有没有一个很好的解决方案来实现这样的扩展方法?或者我应该坚持使用示例中经过尝试和测试的路线
编辑
正如评论中指出的那样,我似乎有点过于简单化了,没有找到问题的根源。下面是实际调用我的IsDefaultValue()的内容:
现在很明显,.GetValue总是作为System.Object返回。不明飞行物
在扩展方法中仍然可以将对象作为其基础类型吗?很抱歉给您带来混淆。请看一下:
static class Program
{
static void Main()
{
int a = 1;
Console.WriteLine("a.IsDefaultValue() : " + a.IsDefaultValue());
a = 0;
Console.WriteLine("a.IsDefaultValue() : " + a.IsDefaultValue());
object obj = new object();
Console.WriteLine("obj.IsDefaultValue() : " + obj.IsDefaultValue());
obj = null;
Console.WriteLine("obj.IsDefaultValue() : " + obj.IsDefaultValue());
int? b = 1;
Console.WriteLine("b.IsDefaultValue() : " + b.IsDefaultValue());
b = null;
Console.WriteLine("b.IsDefaultValue() : " + b.IsDefaultValue());
Console.ReadKey(true);
}
static bool IsDefaultValue<T>(this T value)
{
if (ReferenceEquals(value, null))
{
return true;
}
var t = value.GetType();
if (t.IsValueType)
{
return value.Equals(Activator.CreateInstance(value.GetType()));
}
return false;
}
}
静态类程序
{
静态void Main()
{
INTA=1;
Console.WriteLine(“a.IsDefaultValue():”+a.IsDefaultValue());
a=0;
Console.WriteLine(“a.IsDefaultValue():”+a.IsDefaultValue());
object obj=新对象();
Console.WriteLine(“obj.IsDefaultValue():”+obj.IsDefaultValue());
obj=null;
Console.WriteLine(“obj.IsDefaultValue():”+obj.IsDefaultValue());
int?b=1;
Console.WriteLine(“b.IsDefaultValue():”+b.IsDefaultValue());
b=零;
Console.WriteLine(“b.IsDefaultValue():”+b.IsDefaultValue());
Console.ReadKey(true);
}
静态布尔IsDefaultValue(此T值)
{
if(ReferenceEquals(value,null))
{
返回true;
}
var t=value.GetType();
if(t.IsValueType)
{
返回值.Equals(Activator.CreateInstance(value.GetType());
}
返回false;
}
}
显然有效(我必须说,我确信另一种方法应该有效,但不有效)我看不到您正在描述的行为,使用
3.IsValueDefault()
调用您的方法,并在扩展方法中添加控制台。WriteLine(t)
在控制台上生成预期的System.Int32
<方法中的code>typeof(value)也可能是编译器错误。你没告诉我们什么?我也无法将“始终获取对象”复制为类型。当你调用该方法时,你确定I
的设计时类型称为int
?如中所示,您没有如下内容:objecti=3;bool amIaDefaultValue=i.IsDefaultValue()代码>?(另一方面,可以说您可能希望使用value.GetType()
(检查null!)不管怎样,就像您传入一个值类型作为基本对象
,或者传入一个它正在实现的接口,您将得到不正确的结果,因为默认值(T)
将返回null
)我不理解这个问题,但是要验证某个东西有默认值并不简单,像公共静态bool IsDefaultValue(这个T值){返回值==null | | value.Equals(default(T))}
?(cont),这可能不是一个可行的解决方案。除非您需要检查由值类型实现的接口,否则我认为您可以简单地检查null
并始终返回true
,否则请像现在这样执行值类型检查。如果它是引用类型且值非空,则返回false
。如果它是值类型,请对照默认实例检查它。对于int?类型,IsDefaultValue()为0返回true,为null。对于null,它应该只返回true。我的印象是可空类型和泛型不能很好地结合在一起。
foreach (var imprintProperty in deltas.GetType().GetProperties())
{
var value = imprintProperty.GetValue(deltas);
if (!value.IsDefaultValue())
{
// get corresponding prop in programmable area
var programmableProp = progarea.GetType().GetProperty(imprintProperty.Name);
if (programmableProp != null)
programmableProp.SetValue(progarea, value);
}
}
static class Program
{
static void Main()
{
int a = 1;
Console.WriteLine("a.IsDefaultValue() : " + a.IsDefaultValue());
a = 0;
Console.WriteLine("a.IsDefaultValue() : " + a.IsDefaultValue());
object obj = new object();
Console.WriteLine("obj.IsDefaultValue() : " + obj.IsDefaultValue());
obj = null;
Console.WriteLine("obj.IsDefaultValue() : " + obj.IsDefaultValue());
int? b = 1;
Console.WriteLine("b.IsDefaultValue() : " + b.IsDefaultValue());
b = null;
Console.WriteLine("b.IsDefaultValue() : " + b.IsDefaultValue());
Console.ReadKey(true);
}
static bool IsDefaultValue<T>(this T value)
{
if (ReferenceEquals(value, null))
{
return true;
}
var t = value.GetType();
if (t.IsValueType)
{
return value.Equals(Activator.CreateInstance(value.GetType()));
}
return false;
}
}