Obiekty i przekazywanie wartości

0

Witam, mam pewien problem w pisaniu skryptu do AutoCAD w C#. Otóż w LISP mogłem tworzyć zmienne globalne np. wspolczynnikSkali, który był ustalany na początku skryptu i był stały przez cały czas jego wykonania. Służył do wyliczania wielkości tworzonego tekstu opisów oraz do wyliczania długości użytych kabli, rur, etc. Dlatego stworzyłem instancję PrzestrzenSkaliTegoRysunku, który ten współczynnik przechowuje, ale używanie go nie jest tak wygodne jak tego bym sobie życzył. Czy istnieje jakieś inne rozwiązanie niż przekazywanie tej zmiennej do metod przez wartość? Tak żeby klasy, które korzystają z współczynnika referowały do niego... Gdyby tak się dało to klasa RysowanieObiektow mogłaby być statyczna, a ciągłe powielanie tej zmiennej w przyszłych klasach będzie trochę dziwne. Proszę o sugestie. Poniżej poglądowy wycinek kodu, jak to mam rozwiązane obecnie.

 
public class MyCommands // program
{
    private PrzestrzenModelu przestrzenTegoModelu;
    private RysowanieObiektow rysowanieObiektow;

    private void MyCommand()// odpowiednik Main()
    {
        przestrzenTegoModelu = new PrzestrzenModelu();
        przestrzenTegoModelu.UstawSkaleIWspolczynnikSkali(100);// ustal wspolczynnikSkali

        rysowanieObiektow = new RysowanieObiektow(przestrzenTegoModelu.DzielnikSkaliModelu());

        rysowanieObiektow.RysujTekstDB(punktBazowy2d, 2.0, "Test");
    }
}

public class PrzestrzenModelu
{

    private int skalaModelu;
    private int wspolczynnikSkali;

    public void UstawSkaleIWspolczynnikSkali(int skalaPobrana)
    {
        skalaModelu = skalaPobrana;
        wspolczynnikSkali = 1000 / skalaModelu;
    }

    public int SkalaModelu()
    {
        return skalaModelu;
    }

    public int WspolczynnikSkali()
    {
        return wspolczynnikSkali;
    }

}

public class RysowanieObiektow
{
    public RysowanieObiektow(int DzielnikSkaliModelu) { mnoznikRysowania = DzielnikSkaliModelu; }

    private int mnoznikRysowania;

    public void RysujTekstDB(Point2d punktBazowy, double wysokoscTekstu, string tekstString)
    {

        double wysokoscTekstuXMnoznik = wysokoscTekstu * mnoznikRysowania;

        DBText acText = new DBText();
        acText.Position = punktBazowy3d;
        acText.Height = wysokoscTekstuXMnoznik;
        acText.TextString = tekstString;
        rekordyTabeliBlokow.AppendEntity(acText);
        acTrans.AddNewlyCreatedDBObject(acText, true);
        acTrans.Commit();
    }
}
0

Kilka drobnych uwag. Zazwyczaj w C# dla prywatnych pól stosuje się podkreślenie w nazwie. Druga sprawa, skorzystaj z propertiesów...

public class PrzestrzenModelu
{
    public int Skala;
    public int WspolczynniSkali { get { return Skala/1000; } }
}

Poza tym zdefiniuj konstruktor i wtedy będziesz miał...

public class PrzestrzenModelu
{
    public int Skala;
    public int WspolczynniSkali { get { return Skala/1000; } }

    public PrzestrzenModelu( int skala )
    { 
         Skala = skala;
    } 
}

public class MyCommands // program
{
    private PrzestrzenModelu przestrzenTegoModelu;
    private RysowanieObiektow rysowanieObiektow;
 
    private void MyCommand()// odpowiednik Main()
    {
        przestrzenTegoModelu = new PrzestrzenModelu(100);
    }
}
0

możesz użyć pól albo właściwości statycznych (static). Nie trzeba przekazywać wtedy nic do obiektu, a do pola odwołujesz się przez NazwaKlasy.NazwaPola bez tworzenia obiektu.
Inna sprawa, czy to będzie dobre rozwiązanie.

0

Nabazgrałem coś takiego i chyba będzie działało, tak, jak chciałem. Czemu masz wątpliwości czy to dobre rozwiązanie?

    public static class PrzestrzenModelu
    {
        public static readonly object[] listaSkal = new object[] { "1", "10", "100", "1000" };   

        private static int skalaModelu;
        private static int wspolczynnikSkali;

        public static int SkalaModelu
        {
            get { return skalaModelu;}
            set { skalaModelu = value; wspolczynnikSkali = 1000 / skalaModelu;}            
        }

        public static int WspolczynnikSkali
        {
            get { return wspolczynnikSkali; }
        }
    }
 
0
    public static class PrzestrzenModelu
    {
        public static readonly object[] listaSkal = new object[] { "1", "10", "100", "1000" };   

        private static int skalaModelu;
        private static int wspolczynnikSkali;

        public static int SkalaModelu
        {
            get { return skalaModelu;}
            set { skalaModelu = value; wspolczynnikSkali = 1000 / skalaModelu;}            
        }

        public static int WspolczynnikSkali
        {
            get { return wspolczynnikSkali; }
        }
    }
 

Dobre, nie dobre - ciężko określić. Jeżeli chcesz mieć globalną stałą, to właśnie readonly static jest ok. Z tym, że Twój kod można znacząco skrócić. :)

    public static class PrzestrzenModelu
    {
        public static readonly object[] listaSkal = new object[] { "1", "10", "100", "1000" };   

        public static int WspolczynnikSkali { get { return 1000 / skalaModelu; } }
        public static int SkalaModelu { get; set; }
    }
 

I nie widzę powodu żeby listaSkal była object, używasz stringa to użyj typu string.

0

Dobra, wrzuciłem string zamiast obiekt. Ale jeszcze takie pytanko mam, czy na pewno można używać właściwości w charakterze pól? Gdzieś czytałem, że nie powinno się tego robić, bo do właściwości nie można używać REF i OUT... Czy to prawda, czy coś mylę?

0

Who cares, jeżeli używasz "ref" i "out" to na 99% robisz coś źle.

0
dasdsasdasdsa napisał(a):

Zazwyczaj w C# dla prywatnych pól stosuje się podkreślenie w nazwie.

Marne to zazwyczaj, gdy jedni programiści zazwyczaj tak piszą, inni zazwyczaj nie, a jeszcze inni wcale.

1 użytkowników online, w tym zalogowanych: 0, gości: 1