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

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

问题描述

Martin Fowler的重构讨论了创建Null对象以避免大量的

  if(myObject == null)

测试。
什么是正确的方法?我的尝试违反了构造函数中的虚拟成员调用规则。
这是我的尝试:

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

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


解决方案

我倾向于同意 Wyatt Barnett的回答< a>在创建这些类型的null对象时应该显示出约束。也就是说,有一些很好的理由这样做。有时候



我也倾向于同意 Supertux的答案,因为空对象的整个点是不需要检查它是否为null,所以你应该丢失IsNull属性。如果您真的觉得需要IsNull属性,那么请再次阅读Wyatt的回复并重新考虑。



并且谢谢 CraigTP的好链接更多信息。好的东西。



现在我将假设在你的真正的代码中,你实际上有一个构造函数,试图设置Name或Species的值(不管你真正的代码等同于什么叫做)。否则,为什么会得到构造函数中的虚拟成员调用警告/错误?我使用新的MyProperty {get;组; }自己的快捷方式(特别是在结构体中使用时,不要让我开始编写序列化版本)。您的解决方案是不使用快捷方式,而是以旧式的方式。

  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 {}
}
}

这解决了在构造函数中设置虚拟属性的问题。相反,您正在设置您的私有字段值(如果使用快捷方式,则您无法引用该参数)。要获得额外的信用,请编译这两种方法,并使用反射器查看生成的程序集。



我使用{get;组; }快捷方式,我越不喜欢。


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天全站免登陆