Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/visual-studio/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#将属性/字段的值设置为无_C# - Fatal编程技术网

C#将属性/字段的值设置为无

C#将属性/字段的值设置为无,c#,C#,我认为这是一个常见的问题。假设我有一个典型的Person类和一个Car类,其中字段/属性所有者的类型为Person: public class Car { Person owner; } 但有时我希望车没有主人。处理这个问题的推荐方法是什么。可为空的类型不起作用,因为引用类型已经可以为空。(编辑:澄清,我的意思是您不能使用Person?owner;) 我可以添加一个bool字段/属性:hasOwner,但这似乎相当冗长,因此我考虑在Person类中创建一个静态成员,类型

我认为这是一个常见的问题。假设我有一个典型的Person类和一个Car类,其中字段/属性所有者的类型为Person:

public class Car
{
    Person owner;        
}
但有时我希望车没有主人。处理这个问题的推荐方法是什么。可为空的类型不起作用,因为引用类型已经可以为空。(编辑:澄清,我的意思是您不能使用Person?owner;)

我可以添加一个bool字段/属性:hasOwner,但这似乎相当冗长,因此我考虑在Person类中创建一个静态成员,类型不为Person,如下所示:

namespace ConsoleApplication2
{
public class Person
{
    public static Person none;
    public int age;

    static Person()
    {
        none = new Person();
    }
}

public class Car
{
    public Person owner;
}

class Program
{
    static void Main(string[] args)
    {
        Car dumped = new Car();
        dumped.owner = Person.none;
        Console.ReadLine();
    }
}
}
这是编译和运行的,尽管我还没有在实际应用程序中使用它。然后我想我可以创建一个包含none成员的泛型类:

namespace ConsoleApplication2
{
public class NoneMember<T> where T : new()
{
    public static T none;

    static NoneMember ()
    {
        none = new T();
    }
}

public class Person: NoneMember<Person>
{        
}

public class Car
{
    public Person owner;
}

class Program
{
    static void Main(string[] args)
    {
        Car dumped = new Car();
        dumped.owner = Person.none;
        if (dumped.owner == Person.none)
            Console.Write("This car has no owner");
        Console.ReadLine();
    }
}
}
命名空间控制台应用程序2
{
公共类非成员,其中T:new()
{
公共静态T无;
静态非成员()
{
无=新的T();
}
}
公共类人员:非成员
{        
}
公车
{
公众人物所有者;
}
班级计划
{
静态void Main(字符串[]参数)
{
汽车报废=新车();
.owner=Person.none;
如果(dumped.owner==Person.none)
控制台。写(“这辆车没有主人”);
Console.ReadLine();
}
}
}
它编译并运行,但如果您想继承person类的形式,使用泛型和非泛型的韵文,则会出现问题。经验丰富的c#程序员的想法将不胜感激

编辑:使用null表示none的问题是不能将null作为方法/构造函数参数传递。null表示未设置值,与value is none不同


Edit2:当我传递空参数时,我以为我会抛出异常。不知道发生了什么事。我不知道现在是否可以重现错误。

这两种方法都是有效的。您可能会发现,大多数应用程序只是将属性保留为
null
,并使用一个特殊值来指示空值通常用于值类型(
TimeSpan.Min
等)。

我通常将其保留原样,如果车主为null,这意味着它没有车主。如果有值,则无需复杂化—它有所有者,否则它没有(系统已知的)所有者。
此策略的例外情况是,当您需要日志数据库时,但在这种情况下,您通常可以拥有版本化的汽车和车主,并使用相同的原则。

的确,为什么不使用空值来解决我们的问题呢。如果owner为null,则表示owner根本不存在…

第一个解决方案是在设计模式中称为null对象的东西。 通常情况下,它的实现略有不同,您创建了一个从Person继承的新类

public class Person
{
    public int age;
}

public class NoPerson :  Person
{
}

然后您可以使用
typeof()
语句验证这一点

是的,当您继承时,静态属性/字段有点奇怪。一个框架示例是IMO希望在更专业的类上使用的字段

如果您希望从Person继承,并且希望在继承的类中强制执行“此人不是任何人”,那么我的建议是将此概念添加到类本身

如果您创建了一个虚拟方法,该方法返回true或false,无论某人是否为“nobody”,您的派生类都可以扩展此检查以满足其各自类的需要:

public class Person
{
    public Person()
    {
        // This constructor will create a "nobody"
    }

    public Person(string name)
    {
        // Proper initialization
        this.Name = name;
        _isNobody = false;
    }

    public string Name { get; set; }

    public virtual bool IsNobody
    {
        get 
        {
            return String.IsNullOrEmpty(this.Name) == false;
        }
    }

    // TODO: Maybe override Equals/==/GetHashCode to take IsNobody into account
}
被覆盖的
人员
的一个简单示例可以是定义为“无人”的员工,如果基类(人员)说是,或者如果没有设置员工编号:

public class Employee : Person
{      
    public int EmployeeNumber { get; set; }
    public override bool IsNobody
    {
        return base.IsNobody || EmployeeNumber == -1;
    }
}

当然,您可以将上述内容与类上的静态字段结合起来,这样在Person类上就有了一个

public static readonly Person Nobody = new Person();
对于派生类(注意这里修饰符的用法)


我从未在野外见过这种方法(使用“新”修饰符),我个人会非常不愿意使用它,但如果它在你的领域有意义,它可能是一种替代方法。

赋予
空值的意义是一种有效的方法,但总的来说,我觉得在这种情况下获得“更丰富”的支持确实更可取

您始终可以为引用类型构建自己的“可空类型”。您将没有编译器支持(例如,没有
人?
),但您可以获得非常接近的东西


例如,查看(查找
选项
,文章的其余部分很有趣,但不在您的问题范围内:-)

为什么将
Person
变量设置为
null
不是选项?同意,请您解释一下“可空类型不起作用,因为引用类型已经可以空了。”@完全正确。为什么要重新发明轮子?@Morawski-dunno。如果你重新发明它,你可以从一开始就对它进行镀铬?我的意思是,
Person-owner=null有什么问题?可为null的类型只是让您拥有一个null值类型。对于可为null的类型,我认为监视器值没有什么意义。问题是您不能将null作为方法/构造函数参数传递。null表示未设置值,与value is none不同。@Rich Olvier“您不能将null作为方法/构造函数参数传递”-当然可以。没有硬性规定
null
表示“未设置值”。最后,
null
表示您希望它的意思。如果您确实需要区分“未设置值”和“无”,那么您有几个选项-例如,如上所述的特殊“空对象”,相当于
Nullable
的holder结构,或组件模型
XyzSpecified
的侧车属性。它们都有优点和缺点,选择取决于您的预期用途。@Morawski是的,您是对的。我不确定发生了什么,我以为当我传递null时会抛出异常。因此我的任务。可能有人不喜欢它。。。我认为这是一个有效的方法,如果你
new public static readonly Employee Nobody = new Employee();