[.NET C#] Nullable native types ivm Database

Pagina: 1
Acties:

  • vinnux
  • Registratie: Maart 2001
  • Niet online
Database velden kunnen de waarde NULL (niet gerefereed bevatten) hebben.
Dit geld NIET ook voor velden die binnen .NET gerepresenteerd worden door native type, zoals bijvoorbeeld int, bool, long etc.
Echter is het niet mogelijk om deze velden de waarde NULL te geven.

Nu heb ik situaties waarin ik het volledige bereik van native type variabele wil gebruiken, maar het toch mogelijk is dat de waarde NULL kan zijn. Bij een bool is dit al snel het geval . De waarde kan true of false zijn maar ik wil ook de waarde NULL hebben.

Om dit "te kort" te kunnen compenseren heb ik de volgende oplossingen bedacht:
1. Extra velden.
Je kunt een extra variabele aanmaken die aangeeft of het veld NULL is.
code:
1
2
bool waardeIsNull;
int waarde;

Dit heeft als voordeel dat de variabele waarde nog steeds als native value reageert en weining ruimte in beslag neem. Echter vind ik het erg omslachtig en voelt het niet goed aan. Ik controleer liever of een waarde NULL is door waarde == null.
2. Een object maken waarin de native type wordt opgenomen
Dit heeft als voordeel dat er natuurlijk mee om gegaan kan worden, echter verliest dit object wel de native type functionaliteit.

Hoe lossen jullie dit op?
Is het mogelijk om optie 2 toe te passen en er toch voor te zorgen dat het object reageert als native type en dan vooral dat ie by value wordt doorgegevn ipv by reference?

Is het mogelijk om b.v. dit te doen: int a = (int) new IntegerOwn(2); ?
En zo ja hoe defineer ik dan in IntegerOwn dat deze cast mogelijk is?

[ Voor 7% gewijzigd door vinnux op 22-12-2005 12:23 ]


  • kenneth
  • Registratie: September 2001
  • Niet online

kenneth

achter de duinen

.NET 2.0 ondersteunt nullable types.

C#:
1
2
3
4
5
6
7
8
int? foo;

foo = null;

// ...

if (foo == null)
    // ....

Look, runners deal in discomfort. After you get past a certain point, that’s all there really is. There is no finesse here.


  • vinnux
  • Registratie: Maart 2001
  • Niet online
kenneth schreef op donderdag 22 december 2005 @ 12:27:
.NET 2.0 ondersteunt nullable types.

C#:
1
2
3
4
5
6
7
8
int? foo;

foo = null;

// ...

if (foo == null)
    // ....
Helaas beschikken de meeste systemen nog niet over .NET 2.0 en moet ik het voor nu lossen in de 1 serie.

  • whoami
  • Registratie: December 2000
  • Laatst online: 17:18
Als je voor die 2de optie kiest, dan kan je dat casten doen dmv operator overloading geloof ik.
(Althans, ik zie net in de doc's dat je de cast operator niet kunt overloaden, maar mbhv de explicit en implicit keywords kan je wel user defined conversies definieren.

Echter, als je die 2de manier gebruikt, en daar echt een nieuwe 'class' voor maakt, dan moet je ook oppassen dat je niet de hele tijd loopt te boxen/unboxen.

https://fgheysels.github.io/


  • Plekuz
  • Registratie: September 2002
  • Laatst online: 02-01 15:26

Plekuz

available in strong mint

Of je gebruikt de SqlInt32 etc structures uit de System.Data.SqlTypes boom ..

"There he goes. One of God's own prototypes. Some kind of high powered mutant never even considered for mass production. Too weird to live, and too rare to die."


  • vinnux
  • Registratie: Maart 2001
  • Niet online
Oplossing twee wordt voor bools besproken.
MSDN : ms-help://MS.MSDNQTR.2003FEB.1033/csref/html/vcwlkOperatorOverloadingTutorial.htm
C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
    public struct DBBool {
        // The three possible DBBool values:
        public static readonly DBBool dbNull = new DBBool(0);
        public static readonly DBBool dbFalse = new DBBool(-1);
        public static readonly DBBool dbTrue = new DBBool(1);
        // Private field that stores -1, 0, 1 for dbFalse, dbNull, dbTrue:
        int value; 

        // Private constructor. The value parameter must be -1, 0, or 1:
        DBBool(int value) {
            this.value = value;
        }

        // Implicit conversion from bool to DBBool. Maps true to 
        // DBBool.dbTrue and false to DBBool.dbFalse:
        public static implicit operator DBBool(bool x) {
            return x? dbTrue: dbFalse;
        }

        // Explicit conversion from DBBool to bool. Throws an 
        // exception if the given DBBool is dbNull, otherwise returns
        // true or false:
        public static explicit operator bool(DBBool x) {
            if (x.value == 0) throw new InvalidOperationException();
            return x.value > 0;
        }

        // Equality operator. Returns dbNull if either operand is dbNull, 
        // otherwise returns dbTrue or dbFalse:
        public static DBBool operator ==(DBBool x, DBBool y) {
            if (x.value == 0 || y.value == 0) return dbNull;
            return x.value == y.value? dbTrue: dbFalse;
        }

        // Inequality operator. Returns dbNull if either operand is
        // dbNull, otherwise returns dbTrue or dbFalse:
        public static DBBool operator !=(DBBool x, DBBool y) {
            if (x.value == 0 || y.value == 0) return dbNull;
            return x.value != y.value? dbTrue: dbFalse;
        }

        // Logical negation operator. Returns dbTrue if the operand is 
        // dbFalse, dbNull if the operand is dbNull, or dbFalse if the
        // operand is dbTrue:
        public static DBBool operator !(DBBool x) {
            return new DBBool(-x.value);
        }

        // Logical AND operator. Returns dbFalse if either operand is 
        // dbFalse, dbNull if either operand is dbNull, otherwise dbTrue:
        public static DBBool operator &(DBBool x, DBBool y) {
            return new DBBool(x.value < y.value? x.value: y.value);
        }

        // Logical OR operator. Returns dbTrue if either operand is 
        // dbTrue, dbNull if either operand is dbNull, otherwise dbFalse:
        public static DBBool operator |(DBBool x, DBBool y) {
            return new DBBool(x.value > y.value? x.value: y.value);
        }

        // Definitely true operator. Returns true if the operand is 
        // dbTrue, false otherwise:
        public static bool operator true(DBBool x) {
            return x.value > 0;
        }

        // Definitely false operator. Returns true if the operand is 
        // dbFalse, false otherwise:
        public static bool operator false(DBBool x) {
            return x.value < 0;
        }

        // Overload the conversion from DBBool to string:
        public static implicit operator string(DBBool x) {
            return x.value > 0 ? "dbTrue"
                : x.value < 0 ? "dbFalse"
                : "dbNull";
        }

        // Override the Object.Equals(object o) method:
        public override bool Equals(object o) {
            try {
                return (bool) (this == (DBBool) o);
            }
            catch {
                return false;
            }
        }

        // Override the Object.GetHashCode() method:
        public override int GetHashCode() {
            return value;
        }

        // Override the ToString method to convert DBBool to a string:
        public override string ToString() {
            switch (value) {
                case -1:
                    return "DBBool.False";
                case 0:
                    return "DBBool.Null";
                case 1:
                    return "DBBool.True";
                default:
                    throw new InvalidOperationException();
            }
        }
    }

[ Voor 13% gewijzigd door vinnux op 22-12-2005 13:13 ]


  • Riegstar
  • Registratie: Februari 2003
  • Niet online

Riegstar

Wadapatja!

en dan DBNull.Value gebruiken voor null.

  • marrik
  • Registratie: Augustus 2003
  • Laatst online: 20-07-2025

marrik

Live long and prosper

Op sourceforge is een heel project te vinden over nullabletypes: http://nullabletypes.sourceforge.net/. Deze zou je zo in je project moeten kunnen hangen.

Marrik


  • EfBe
  • Registratie: Januari 2000
  • Niet online
Gebruik een boolean flag. Zelf structs maken van types is leuk, maar in databinding scenario's werken ze vaak niet.

Creator of: LLBLGen Pro | Camera mods for games
Photography portfolio: https://fransbouma.com


  • Plekuz
  • Registratie: September 2002
  • Laatst online: 02-01 15:26

Plekuz

available in strong mint

Waarom haakt niemand in op mijn oplossing? Dat zijn standaard nullable structs in C# ...

"There he goes. One of God's own prototypes. Some kind of high powered mutant never even considered for mass production. Too weird to live, and too rare to die."


  • EfBe
  • Registratie: Januari 2000
  • Niet online
Weakling schreef op donderdag 22 december 2005 @ 15:01:
Waarom haakt niemand in op mijn oplossing? Dat zijn standaard nullable structs in C# ...
Omdat die bout zijn voor algemene doeleinden:
- geen databinding
- niet serializable.
- in VB.NET 2002/3 kun je niet doen: object.IntField = 10 want VB.NET 2002/3 ondersteunt geen operator overloading en roept de implicit conversion operators dus niet aan, je moet dan doen: object.IntField = New SqlInteger(10)

Creator of: LLBLGen Pro | Camera mods for games
Photography portfolio: https://fransbouma.com

Pagina: 1