【问题标题】:How to create a class that uses a generic type that allows nullable and non-nullable types如何创建一个使用允许可空和不可空类型的泛型类型的类
【发布时间】:2010-10-11 14:32:41
【问题描述】:

我正在尝试创建一个类以用作其他对象中的字段,该类可以保存临时未保存的值,直到在对象上调用 SaveChanges 方法,以便我可以将值传递给存储的过程,这将使用新值更新所有非空字段,并将空字段保留为其原始值。

我希望能够做到这一点:

private Field<int> MyInt;
private Field<int?> MyNullableInt;
private Field<string> MyString;

然后可以像这样使用 Field 对象:

MyInt = new Field<int>(1);    // initialise with a value
MyInt.Value = 2;              // assign a new value internally marking it as having a new value
int x = MyInt.Value;          // read the current value
int? newInt = MyInt.NewValue; // read the newly set value, or null if there is no new value

我希望能够创建以下字段:

  • 在 db 中具有 NOT NULL 约束的值类型,例如 int、bool 等。
  • 值类型,例如 int?、bool? 等,允许在 db 中使用 NULL。
  • 总是可以为空的引用类型,例如字符串。

我仍在学习泛型,但我开始了解它们,但是,我有点坚持这一点,因为我可以根据需要创建一个 Field 对象,该对象与不可为空的类型一起使用,或者可以为空的类型,但不能两者兼有。

这是我迄今为止想出的:

protected class Field<T> where T : struct {
    private T _Field;
    private bool _IsNew;

    public Field(T InitialValue) {
        _Field = InitialValue;
        _IsNew = false;
    }

    public T Value {
        get { return _Field; }
        set { 
            if (!_Field.Equals(value)) { 
                _Field = value; 
                _IsNew = true; 
            } 
        }
    }

    public Nullable<T> NewValue {
        get {
            if (_IsNew) {
                _IsNew = false;
                return _Field;
            }
            return null; 
        }
    }

    public bool IsNew { get { return _IsNew; } }

}

这很好用。我还可以将类型约束更改为where T : class,并在NewValue 方法上将Nullable&lt;T&gt; 更改为T,这使它适用于可为空的类型,但我如何让它适用于所有数据类型?我真的需要创建两个不同的类来处理这两种不同的场景吗?

谢谢, 本

【问题讨论】:

  • 这是一个附注,但请将您的字段和变量小写。

标签: c# generics nullable


【解决方案1】:

是什么阻止了你做你想做的事?我猜这是 where 约束。如果你放下它,我看不出问题出在哪里。

编辑

你不能同时拥有它。要么你的泛型类知道一些关于分配给值的空值,然后你不能将值类型(如 int)作为允许的类型,或者你不知道。

如果是前者,你的泛型类需要约束,你不能将它用于像 int 这样的值类型

在后一种情况下,不需要约束,您仍然可以将 null 分配给值 IF 通用参数属于引用类型

【讨论】:

  • 如果我放弃 where 约束,那么它不会让我为 NewValue 返回 null。
  • 尝试默认(T)而不是返回null
  • 那么您应该将私有字段 MyInt 从您要在此处涵盖的内容列表中排除
  • 是的,约束不仅仅是预防性的。一旦你确保类型继承或实现了某些东西,你的代码就可以依赖它了。
  • @mfeingold:我不能,因为有人可以给我答案,将其更改为使用可空类型而不是不可空类型,但我想要涵盖两者的东西。跨度>
猜你喜欢
  • 2017-09-25
  • 1970-01-01
  • 1970-01-01
  • 2017-06-25
  • 1970-01-01
  • 2021-02-17
  • 1970-01-01
  • 2018-08-08
  • 2020-09-21
相关资源
最近更新 更多