如何创建在C#中一个空对象 [英] How do I create a Null Object in C#

查看:202
本文介绍了如何创建在C#中一个空对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Martin Fowler的重构讨论创建空的对象,避免大量的



 如果(myObject的== NULL)

测试。
什么是做到这一点的正确方法?我试图违反规则,在构造虚拟成员电话。
这是我在它的尝试:

 公共类动物
{
公共虚拟字符串名称{搞定;组; }
公共虚拟字符串物种{搞定;组; }
公共虚拟BOOL ISNULL
{
获得{返回false; }
}
}

公共密封类NullAnimal:动物
{
公众覆盖字符串名称
{
{返回空值; }
组{}
}
公众覆盖字符串物种
{
{返回NULL; }
组{}
}
公共虚拟BOOL ISNULL
{
获得{返回true; }
}
}


解决方案

我倾向于悦巴尼特的答案中,你应该创建这些形形色色的空的对象时,表现出克制。尽管如此,也有这样一些很好的理由。有时。



我也倾向于使用的在一个空对象的整点超级企鹅的回答是不是需要检查它是否为空,所以你应该失去ISNULL财产。如果你真的觉得你需要的ISNULL属性,然后再阅读悦的响应和重新考虑。



和感谢你的 CraigTP了很好的链接以获取更多信息。好东西。



现在我会假设你的真实代码,你实际上有一个尝试设置名称或种类(值构造无论你真正的代码等同可能叫做)。否则,你为什么会得到警告/错误的,在构造虚拟成员电话?我碰到一对夫妇使用新奇myProperty的时候类似的问题{搞定;组; }快捷自己(在结构中使用特别是当,不要让我开始对序列化版本)。您的解决方案是不使用的快捷方式,而是做了老式的方式。

 公共类动物{
保护动物(){}

公共动物(字符串名称,串种){
_Name =名称;
_Species =种;
}

公共虚拟字符串名称{
{返回_Name; }
集合{_Name =价值; }
}
私人字符串_Name;

公共虚拟字符串物种{
{返回_Species; }
集合{_Species =价值; }
}
私人字符串_Species;
}

公共密封类NullAnimal:动物{
公众覆盖字符串名称{
{返回的String.Empty; }
组{}
}
公众覆盖字符串物种{
{返回的String.Empty; }
集合{}
}
}

这解决了在构造函数中设置你的虚拟财产问题。相反,你要设置你的私有字段的值(你不必引用的能力,如果您使用快捷键)。对于额外的信用,编撰这两种方法,并使用反射来看看导致组件



我越使用{搞定;组; }快捷方式,更多的我不喜欢。


Martin Fowler's Refactoring discusses creating Null Objects to avoid lots of

if (myObject == null)

tests. What is the right way to do this? My attempt violates the "virtual member call in constructor" rule. Here's my attempt at it:

public class Animal
{
    public virtual string Name { get; set; }
    public virtual string Species { get; set; }
    public virtual bool IsNull 
    { 
        get { return false; }
    }
}

public sealed class NullAnimal : Animal
{
    public override string Name
    {
        get{ return "NULL"; }
        set { }
    }
    public override string Species
    {
        get { return "NULL"; }
        set { }
    }
    public virtual bool IsNull
    {
        get { return true; }
    }
}

解决方案

I tend to agree with Wyatt Barnett's answer in that you should show restraint when creating these kinds of "null" objects. That said, there are some nice reasons for doing so. On occasion.

I also tend to agree with Supertux's answer in that the whole point of a null object is to not need to check whether or not it is null, so you should lose the IsNull property. If you really feel you need the IsNull property, then read Wyatt's response again and reconsider.

And thank you CraigTP for the nice links for more info. Good stuff.

Now I will assume that in your real code you actually have a constructor that is attempting to set the values of Name or Species (whatever your real code equivalent might be called). Otherwise, why would you get the "virtual member call in constructor" warning/error? I've run into a couple of similar problems when using the newfangled MyProperty { get; set; } shortcut myself (particularly when used in structs, and don't get me started about serialization versioning). Your solution is to not use the shortcut, but instead do it the old-fashioned way.

public class Animal {
	protected Animal() { }

	public Animal(string name, string species) {
		_Name = name;
		_Species = species;
	}

	public virtual string Name {
		get { return _Name; }
		set { _Name = value; }
	}
	private string _Name;

	public virtual string Species {
		get { return _Species; }
		set { _Species = value; }
	}
	private string _Species;
}

public sealed class NullAnimal : Animal {
	public override string Name {
		get { return String.Empty; }
		set { }
	}
	public override string Species {
		get { return String.Empty; }
		set { }
	}
}

This solves the problem of setting your virtual properties in the constructor. Instead, you are setting your private field values (something you don't have the ability to reference if you use the shortcut). For extra credit, compile both methods, and use the Reflector to look at the resulting assemblies.

The more I use the { get; set; } shortcut, the more I dislike it.

这篇关于如何创建在C#中一个空对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆