-----------------------------------

Acquista i software ArcGIS tramite Studio A&T srl, rivenditore autorizzato dei prodotti Esri.

I migliori software GIS, il miglior supporto tecnico!

I migliori software GIS, il miglior supporto tecnico!
Azienda operante nel settore GIS dal 2001, specializzata nell’utilizzo della tecnologia ArcGIS e aderente ai programmi Esri Italia Business Network ed Esri Partner Network

-----------------------------------



domenica 13 luglio 2008

Utilizzo del where nei generics

using System;
using System.Collections.Generic;


//Author:Domenico Ciavarella
//http://www.studioat.it
namespace Geometry
{

    public interface IGeometry
    {
        int Dimension { get;}
    }

    public interface IPoint : IGeometry
    {
        bool IsEmpty();
        double X { get; set; }
        double Y { get; set; }
        void SetEmpty();
        double Distance(IPoint pt);
    }



    public class Point : IPoint, ICloneable
    {

        double m_x = double.NaN;
        double m_y = double.NaN;


        public Point(IPoint point)
            : this(point.X, point.Y)
        {

        }
        public Point(double x, double y)
        {

            m_x = x;
            m_y = y;
        }
        public Point()
        { }



        #region IPoint Members
        public bool IsEmpty()
        {
            IPoint p = this as IPoint;
            return (double.IsNaN(p.X) || double.IsNaN(p.Y));
        }

        public void SetEmpty()
        {
            IPoint p = this as IPoint;
            p.X = double.NaN;
            p.Y = double.NaN;
        }

        public double X
        {
            get { return m_x; }
            set { m_x = value; }
        }


        public double Y
        {
            get { return m_y; }
            set { m_y = value; }
        }


        public double Distance(IPoint pt)
        {
            IPoint p = this as IPoint;
            if ((pt.IsEmpty()) || (p.IsEmpty()))
                return double.NaN;
            else
                return Math.Sqrt(Math.Pow(pt.X - p.X, 2) + Math.Pow(pt.Y - p.Y, 2));


        }


        public static Point operator +(Point p1, Point p2)
        {
            return new Point(p1.m_x + p2.m_x, p1.m_y + p2.m_y);
        }


        public static Point operator /(Point p1, double d)
        {
            return new Point(p1.m_x / d, p1.m_y / d);
        }

        #endregion


        #region ICloneable Members

        object ICloneable.Clone()
        {
            return this.MemberwiseClone();
        }



        #endregion

        public override string ToString()
        {
            IPoint p = this as IPoint;

            if (p.IsEmpty())
                return "Point is Null";
            else
                return string.Format("X: {0} Y:{1}", p.X.ToString(), p.Y.ToString());
        }
        public override bool Equals(object obj)
        {
            bool bResult = false;

            IPoint pt = obj as IPoint;
            if (pt != null)
            {
                IPoint ptClass = this as IPoint;
                if ((ptClass.IsEmpty()) && (pt.IsEmpty())) return true;
                if ((!ptClass.IsEmpty()) || (pt.IsEmpty())) return false;
                if ((ptClass.IsEmpty()) || (!pt.IsEmpty())) return false;

                return ((pt.X == ptClass.X) && (pt.Y == ptClass.Y));

            }

            return bResult;
        }
        public override int GetHashCode()
        {
            IPoint pt = this as IPoint;
            if (pt.IsEmpty()) return -1;
            return (int)(Math.Pow(pt.X, 2) + Math.Pow(pt.Y, 2));
        }


        public static explicit operator Point(Envelope envelope)
        {

            return (envelope as IArea).Centroid as Point;

        } 


        #region IGeometry Members

        int IGeometry.Dimension
        {
            get { return 0; }
        }

        #endregion


    }


    public interface IArea
    {
        double Area { get;}
        IPoint Centroid { get;}
    }
    public interface IEnvelope : IGeometry
    {
        double Height { get; }
        double Width { get; }
        Point Origin { get;}
        Point Size { get;}
    }

    public interface ICircle : IGeometry
    {
        double Radious { get;set; }
        IPoint Center { get;set;}
    }

    public class Envelope : IArea, IEnvelope
    {

        private Point m_size;
        private Point m_origin;

        public Envelope(Point origin, Point size)
        {
            m_origin = origin;
            m_size = size;

        }
        public Point Origin
        {
            get { return m_origin; }
        }

        public Point Size
        {
            get { return m_size; }
        }

        public double Height
        {
            get { return Size.Y; }
        }


        public double Width
        {

            get { return Size.X; }

        }





        #region IArea Members

        public double Area
        {
            get { return Height * Width; }
        }
        public IPoint Centroid
        {
            get
            {
                return Origin + (Size / 2.0);
            }
        }

        #endregion

        #region IGeometry Members

        public int Dimension
        {
            get { return 2; }
        }

        #endregion


    }


    public class Circle : IArea, ICircle
    {
        double m_radious = double.NaN;
        IPoint m_center = null;






        public Circle(double radious, IPoint center)
        {
            Center = center;
            Radious = radious;
        }


        #region ICircle Members

        public double Radious
        {
            get { return m_radious; }
            set { m_radious = value; }
        }
        public IPoint Center
        {
            get { return m_center; }
            set { m_center = value; }
        }

        #endregion

        #region IGeometry Members

        public int Dimension
        {
            get { return 2; }
        }

        #endregion

        #region IArea Members

        public double Area
        {
            get { return Math.Pow(Radious,2) * Math.PI; }
        }

        public IPoint Centroid
        {
            get { return Center; }
        }

        #endregion
    }

    public delegate R Operation<T, R>(T geo1, T geo2)
        where R : struct
        where T : IArea;

    public class GeometryBag<T>where T:IArea
    {
        private List<T> geometries = new List<T>();
        public void AddGeometry(T geometry)
        {
            geometries.Add(geometry);
        }
        public double Area
        {
            get
            {
                double totalArea = 0;
                foreach (T geometry in geometries)
                {
                    totalArea += geometry.Area;
                }
                return totalArea;
            }
        }

        public static double Sum(T geometry1,T geometry2)
        {
            return geometry1.Area + geometry2.Area;
        }

    }

}


using System;
using System.Collections.Generic;
using System.Text;
using Geometry;

//Author:Domenico Ciavarella
//http://www.studioat.it

namespace Generics
{
    class Program
    {
        static void Main(string[] args)
        {

            IPoint pPoint = new Point(10d, 2d);

            IPoint pPoint2 = new Point(pPoint);
            Console.WriteLine("Point2 x:{0} y:{1}", pPoint2.X.ToString(), pPoint2.Y.ToString());

            IPoint pPoint3 = new Point();
            Console.WriteLine("Point3 is null: {0}", pPoint3.IsEmpty().ToString());


            ICloneable pPoint4 = pPoint2 as ICloneable;
            IPoint pPoint5 = pPoint4.Clone() as IPoint;
            Console.WriteLine("Point5 x:{0} y:{1} HashCode Point5:{2}", pPoint5.X.ToString(), pPoint5.Y.ToString(), pPoint5.GetHashCode());

            IPoint pPoint6 = new Point();
            Console.WriteLine("Point6 is equal Point3: {0} HashCode Point6:{1} HashCode Point3:{2}", pPoint6.Equals(pPoint3), pPoint6.GetHashCode(), pPoint3.GetHashCode());

            Envelope pEnvelope = new Envelope(new Point(2d, 2d), new Point(5d, 6d));
            Point pPoint7 = (Point)pEnvelope;

            Console.WriteLine("Point7 x:{0} y:{1}", pPoint7.X.ToString(), pPoint7.Y.ToString());


            GeometryBag<IArea> pGeometryBag = new GeometryBag<IArea>();
            pGeometryBag.AddGeometry(new Circle(10.0, pPoint7 as IPoint));
            pGeometryBag.AddGeometry(pEnvelope);

            Console.WriteLine("Total area: {0}", pGeometryBag.Area);


            Operation<IArea, double> op = new Operation<IArea, double>(GeometryBag<IArea>.Sum);


            Console.WriteLine("Total area: {0}", op(new Circle(10.0, pPoint7 as IPoint), pEnvelope));

            Console.ReadLine();


        }


    }






}



Qui puoi scaricare la soluzione in VS2008 Generics