+ Rispondi al Thread
Visualizzazione dei risultati da 1 a 3 su 3

Discussione: Problemi con i Nullable

  1. #1
    Chico non è in linea Scolaretto
    Luogo
    Padova
    Post
    104

    Problemi con i Nullable

    Ciao a tutti.
    Sto lavorando ad una libreria per calcoli di geometria piana. Ho definito alcune strutture (Point2D, Line, Segment, Circumference) e ora sto mettendo a punto gli overload del metodo Intersection che dovrerbbe restituire il/i punto/i di intersezione tra i vari elementi geometrici.
    Se non vi sono intersezioni, il metodo deve ritornare un valore null. Questo caso mi ha dato dei problemi (non accettava "return null").
    Ho fatto così conoscenza dei Nullable e ho risolto modificando la dichiarazione dei metodi ma mi sono arenato alla routine Contain della struttura Segment.

    codice:
            public bool Contain(System.Nullable<Point2D> Point1)
            //Point1 è contenuto in Segment se è contenuto nel rettangolo di cui Segment rappresenta la diagonale
            {
                double Xmin = Math.Min(this.p1.X, this.p2.X);
                double Xmax = Math.Max(this.p1.X, this.p2.X);
                double Ymin = Math.Min(this.p1.Y, this.p2.Y);
                double Ymax = Math.Max(this.p1.Y, this.p2.Y);
                if ((Point1.X >= Xmin) & (Point1.X <= Xmax) & (Point1.Y >= Ymin) & (Point1.Y <= Ymax))
                {
                    return true;
                }
                else
                {
                    return false;
                }
            }
    Mi dà errore in quanto le proprietà X e Y di Point1 non vengono più riconosciute (System.Nullable<Point2D> non contiene una definizione di X). Questa volta non riesco a capire il motivo dell'errore!
    Forse manca qualcosa nella definizione di Point2D che posto integralmente di seguito.
    codice:
        public struct Point2D
        {
            public double X;
            public double Y;
            public Point2D(double Xp, double Yp)
            {
                X = Xp;
                Y = Yp;
            }
    
            public static Point2D operator +(Point2D P1, Point2D P2) 
            {
                Point2D p = new Point2D();
                p.X = P1.X + P2.X;
                p.Y = P1.Y + P2.Y;
                return p;
            }
    
            public static Point2D operator *(float f , Point2D P1)
            {
                Point2D p = new Point2D();
                p.X = f * P1.X;
                p.Y = f * P1.Y;
                return p;
            }
        }
    Spero di essere riuscito a spiegarmi e grazie per chi riesce a darmi una dritta.

  2. #2
    L'avatar di _alka_
    _alka_ non è in linea Very Important Person
    Luogo
    Reggio Emilia
    Post
    1,157
    Il problema sta nel fatto che, quando rendi un tipo "nullabile" usando la struttura Nullable, di fatto stai racchiudendo il tuo valore all'interno di qualcosa di leggermente più complesso, ovvero la struttura che ti consente di assegnare un valore null oltre al valore che normalmente assume la variabile resa "nullabile".
    In pratica, Nullable aggiunge un guscio esteriore al valore.

    Per poter accedere alle proprietà, devi garantire che il valore non sia null.

    Puoi farlo in due modi: tramite il cast del valore al tipo di base, oppure accedendo alla proprietà Value che la struttura Nullable ti mette a disposizione assieme alla proprietà HasValue che ti indica se la variabile contiene effettivamente un valore (true) oppure se è null (false).

    Tradotto in codice, se dichiari una variabile in questo modo
    codice:
    Point2D? p1;
    quando vorrai accedere alle sue proprietà dovrai seguire una di queste strade:

    codice:
    if (p1 != null)
      ((Point2D)p1).X = ...
    oppure
    codice:
    if (p1 != null)
      p1.Value.X = ...
    oppure ancora
    codice:
    if (p1.HasValue)
      p1.Value.X = ...
    e così via.

    Ciao!
    MARCO BREVEGLIERI
    Software and Web Developer, Teacher and Consultant

    Homepage | Blog | Delphi Podcast | Delphi Succinctly (e-book)

  3. #3
    Chico non è in linea Scolaretto
    Luogo
    Padova
    Post
    104
    Grazie _alka_ per la spiegazione molto chiara.
    Ho provato entrambi i metodi. Queste due versioni di Contain funzionano entrambe.

    Cast di Point1
    codice:
            public bool Contain(System.Nullable<Point2D> Point1)
            //Point1 è contenuto nell'istanza di Segment se è contenuto nel rettangolo di cui Segment rappresenta la diagonale
            {
                if (Point1 == null)
                {
                    return false;
                }
                Point2D P = (Point2D)Point1;
                double Xmin = Math.Min(this.p1.X, this.p2.X);
                double Xmax = Math.Max(this.p1.X, this.p2.X);
                double Ymin = Math.Min(this.p1.Y, this.p2.Y);
                double Ymax = Math.Max(this.p1.Y, this.p2.Y);
                if ((P.X >= Xmin) & (P.X <= Xmax) & (P.Y >= Ymin) & (P.Y <= Ymax))
                {
                    return true;
                }
                else
                {
                    return false;
                }
            }
    Uso della proprietà Value
    codice:
            public bool Contain(System.Nullable<Point2D> Point1)
            //Point1 è contenuto nell'istanza di Segment se è contenuto nel rettangolo di cui Segment rappresenta la diagonale
            {
                if (Point1 == null)
                    {
                        return false; 
                    }
                double Xmin = Math.Min(this.p1.X, this.p2.X);
                double Xmax = Math.Max(this.p1.X, this.p2.X);
                double Ymin = Math.Min(this.p1.Y, this.p2.Y);
                double Ymax = Math.Max(this.p1.Y, this.p2.Y);
                if ((Point1.Value.X >= Xmin) & (Point1.Value.X <= Xmax) & (Point1.Value.Y >= Ymin) & (Point1.Value.Y <= Ymax))
                {
                    return true;
                }
                else
                {
                    return false;
                }
            }

+ Rispondi al Thread

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi