代码之家  ›  专栏  ›  技术社区  ›  BG100

如何创建使用允许空类型和不可空类型的泛型类型的类

  •  0
  • BG100  · 技术社区  · 14 年前

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

    我希望能够做到:

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

    然后可以使用这样的字段对象:

    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
    

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

    • 值类型,如int、bool等,在db中具有非空约束。
    • 值类型,如int?,布尔?等,允许在数据库中为空。
    • 引用类型(如字符串)始终可以为空。

    我仍然在学习泛型,但是我开始理解它们,但是,我有点坚持这一点,因为我可以根据需要创建上面使用不可空类型或可空类型的字段对象,但不能同时使用这两种类型。

    这就是我到目前为止想出来的:

    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 和改变 Nullable<T> 只是 T 在newValue方法上,这使得它可以处理可以为空的类型,但是如何让它处理所有数据类型?我真的需要创建两个不同的类来处理两个不同的场景吗?

    谢谢, 本

    1 回复  |  直到 14 年前
        1
  •  2
  •   mfeingold    14 年前

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

    编辑

    你不能两者兼得。泛型类知道将空值赋给该值,然后不能将值类型(如int)作为允许的类型,或者不知道。

    如果前者是这样,那么您的泛型类需要约束,并且不能将其用于int之类的值类型。

    在后一种情况下,不需要约束,您仍然可以将空值赋给该值。 如果 通用参数是引用类型