C#定义类实例永远不能为null(它只包含任何数据)

C#定义类实例永远不能为null(它只包含任何数据),c#,class,instance,C#,Class,Instance,出于好奇:有没有办法创建一个对类实例的引用永远不能设置为null的类? 类似于只有一个只读指针,该指针只能由类本身设置为null 我的想法是: 我希望有一个易于读取/使用的对象,该对象既有数据也没有数据(由hasData=false这样的属性显示)。它始终是可访问的,并且永远不应该为null/指向任何地方,作为一种副作用,它还消除了对象的NullReferenceException,这些对象有时应该没有值,而不需要检查null。在这种情况下,您可能希望使用结构而不是类。类是引用类型,因此其默认值

出于好奇:有没有办法创建一个对类实例的引用永远不能设置为null的类? 类似于只有一个只读指针,该指针只能由类本身设置为null

我的想法是:
我希望有一个易于读取/使用的对象,该对象既有数据也没有数据(由hasData=false这样的属性显示)。它始终是可访问的,并且永远不应该为null/指向任何地方,作为一种副作用,它还消除了对象的NullReferenceException,这些对象有时应该没有值,而不需要检查null。

在这种情况下,您可能希望使用结构而不是类。类是引用类型,因此其默认值为null,因此包含实例的变量可以为null(赋值为null)。没有办法阻止它。另一方面,struct是一个值类型,struct的默认值是一个空的struct,即其成员被设置为默认值的struct(0表示int字段,null表示引用类型的字段等)

结构的示例

public struct Foo
{
    public int Bar;
}
及其用法(注意它没有实例化,但仍然不是null)


有关结构的更多信息,请参见。

此功能尚不存在。Roslyn论坛上对不可为null的引用类型进行了大量讨论:。但当前无法限制引用类型变量赋值
null

您可以改为使用值类型(struct),但它不存储在堆中,也不按值传递


所有其他选项都不能保证有人不会将
null
赋值给引用类型的变量。但是您仍然可以使用类似于模式的东西来简化您的生活(以与普通对象相同的方式处理没有数据的对象)。

正如Anton提到的,您可以使用默认值不能为null的结构。但我想你想要的是更像这样的东西:

public class DataObject
{
    public static bool HasData
    {
        get
        {
            return myObject != null;
        }
    }

    public static DataObject PresistentDataObject
    {
        get
        {
            return myObject;
        }
    }

    static DataObject myObject = new DataObject();
}

这个代码看起来像是坏习惯。也许您希望借助于类似于依赖项注入的单例来避免设置这样的状态类。

如果您的类名为foo,那么您至少会有一个构造函数(可能更多)。在该构造函数中,您将变量赋值为false

public foo(){
    hasData = false;
}
正如@Anton所指出的,只有当变量实例化时,这才有效。 foo f=新的foo()

如果将其分配为null,则它仍然为null: foo f=null

我不确定,我是否正确理解了这个问题。让我补充一点 这里有几点:


希望您误解了术语
Instance
,如果您创建了类的实例,那么它将不会是
null
,让
myClass
成为您已经创建的类。您没有使用
myClass myClassObject
创建该类的任何实例。
myClassObject
只有当类的实例被分配给它时才会成为类的实例,直到那时它才是
null
,这意味着不存在。

通常,这样一个问题背后的动机会驱动解决方案的质量/属性

我认为,这里的动机是避免(错误的)代码的运行时异常,这些代码试图访问空引用,就好像它持有一个实例一样

class Foo<T> {
    T data; // might be null or hold an instance...
    Foo<T>() {
        data = GetInstanceOfTInMysteriousWays(); // might return null...
    }
    bool DoSomething() {
       return data.Value > 5; // might throw an exception...
    }
    // ... more members...
}

现在唯一的问题是,在C#中在哪里可以找到该选项类型?有几个github项目创建了这样的类型(google是你的朋友)。你也可以考虑链接F.Y.Cype库并使用它定义的选项类型,如一个小助手所示。

正如其他人提到的,你需要一个<代码> Stutt。 但是,我们可以从不同的角度(在课堂上)解决这个问题:

因为变量可以指向null,所以让我们以一种不能设置为null的方式定义变量:

private Class1 _c = new Class1();
public Class1 c { get { return _c; } set { if (value != null) _c = value; } }
因此
c
将不会设置为
null


符合您要求的
struct

struct Struct1
{
    public bool hasData { get { return Data != null; } }
    public Class1 Data;
}

你可以在构造函数中将hasData设置为false。我不太明白你在问什么。因此,基本上,您想要一个不能设置为null的静态类?因为构造函数不需要运行,我猜:不需要无法避免,不是吗?@RickRunowski:how?类永远不会为null-对实例的引用可能为null。设计问题是:谁创建了实例?你可以让它返回一个选项,当涉及到实例时,我的解释有点不确定。。你是对的,我只是不想让声明的对象为null/指向任何东西谢谢,除非有一个不可为null的引用类型,这非常接近!谢谢你-这是我想要的,有趣的讲座!好例子+1虽然我在另一篇文章中标记了答案,因为还没有不可为null的引用类型,但这是可行的,thxOption是我一直在寻找的类型,但它并不存在(还没有),我将看看F#和Github项目-非常好的信息
private Class1 _c = new Class1();
public Class1 c { get { return _c; } set { if (value != null) _c = value; } }
struct Struct1
{
    public bool hasData { get { return Data != null; } }
    public Class1 Data;
}