mercoledì 19 dicembre 2012

How to : implement Internal property

Giusto per non perdere il vizio di scrivere due righe di codice ecco che mi capita sotto mano, una di quelle "non troppo" rare occasioni per cui implementare una proprietà Ineternal.


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace propTest
{
    public class entityTest
    {
        public int id { get; private set; }
        public string Name { get; set; }
        public DateTime Timestamp { get; internal set; }
    }

    class Program
    {
        static void Main(string[] args)
        {
            entityTest et = new entityTest();
            /* 
             * The property or indexer 'propTest.entityTest.id' 
             * cannot be used in this context because the set accessor is inaccessible    
             */ 

            et.id = 30;
            et.Name = "Fabio";
            et.Timestamp = DateTime.Now;
        }
    }
}

et.id = 30 non è fattibile perchè la proprietà è privata e quindi di pertinenza di entityTest, il suo scope ( in valorizzazione ) è soltanto nella classe.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace propTest
{
    public class entityTest
    {
        public virtual int id { get; set; }
        public virtual string Name { get; set; }
        public virtual DateTime Timestamp { get; internal set; }
    }

    public class entityTestWrapper : entityTest 
    {
        public new int id { get; private set; }
        public override string Name { get; set; }
        public override DateTime Timestamp { get; internal set; }

        public entityTestWrapper(int newId)
        {
            id = newId;
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            entityTestWrapper et = new entityTestWrapper(30);

            et.Name = "Fabio";
            et.Timestamp = DateTime.Now;

            entityTest etx = new entityTest();
            etx.id = 31;
            etx.Name = "Fabio";
            etx.Timestamp = DateTime.Now;

        }
    }
}

E in questo esempio ci inventiamo come valorizzare l'id privato wrappando l'originale. Ora come otteniamo la valorizzazione di un internal da un name space diverso ?? Semplice non si può...

Seguendo l'esempio è necessario creare un secondo progetto e referenziarlo dal primo  e poi provare a scrivere quanto segue:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace propTestA
{
    public class entityTest
    {
        public virtual int id { get; private set; }
        public virtual string Name { get; set; }
        public virtual DateTime Timestamp { get; internal set; }
    }
}

e quindi:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;


namespace propTest
{
    using propTestA;
    class Program
    {        
        static void Main(string[] args)
        {
            entityTest etx = new entityTest();        
            etx.Name = "Fabio";

            /*
             * Property or indexer 'propTestA.entityTest.Timestamp' cannot be assigned to -- 
             * it is read only    
             */

            etx.Timestamp = DateTime.Now;

        }
    }
}

Morale ... le proprietà internal sono tali per namespace e progetto...

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;


namespace propTestA
{
    public class entityTest
    {
        public virtual int id { get; private set; }
        public virtual string Name { get; set; }
        public virtual DateTime Timestamp { get; internal set; }
    }
}

namespace propTest
{
    using propTestA;
    class Program
    {        
        static void Main(string[] args)
        {
            entityTest etx = new entityTest();        
            etx.Name = "Fabio";
            etx.Timestamp = DateTime.Now;
        }
    }
}
In questo modo funziona anche se il namespace è differente, vince il fatto che appartengono allo stesso progetto.

Nessun commento: