Obiekt klasy może zostać stworzony tylko za pomocą innej klasy.

0

Tak jak w temacie. Powiedzmy, że mam taki kod:

 
public class GlownaKlasa
{
   public GlownaKlasa() {}
   public KlasaPoboczna Zwroc()
   {
      KlasaPoboczna ks = new KlasaPoboczna();
      return ks;
   }
}

public class KlasaPoboczna
{
     public/private KlasaPoboczna() {}
}

W jaki sposób zablokować możliwość stworzenia 'ręcznie' klasy KlasaPoboczna? Tzn, żeby trzeba było użyć metody Zwroc() z GlownaKlasa? Czy da się tak w ogóle?

0

Zastosuj modyfikator internal dla konstruktora?

0

Internal nie pomoże bo bla bla bla ( Do you want to know more? GoTo("MSDN"); )
Na szybko wymodziłem takie cudo:

public class GlownaKlasa
    {
        private class KlasaPoboczna
        {
            public KlasaPoboczna() { }
        }
        public GlownaKlasa() { }
         // tu trza było dać Object, static dałem dla wygody testowania ;)
        static public Object Zwroc()
        {
            KlasaPoboczna ks = new KlasaPoboczna();
            return ks;
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            Object o = GlownaKlasa.Zwroc(); // mniam
            //KlasaPoboczna = GlownaKlasa.Zwroc(); // ble :)
            //KlasaPoboczna(); // ble :)
        }
    }

żeby używać tak zwróconego obiektu by trzeba się pobawić czymś z System.Reflection, dostajesz listę pól i metod obiektu i jedziesz :)

0

Musiałem odkopać kawałek starego kodu żeby sobie przypomnieć co i jak ale już śmiga:

...
using System.Reflection;
...

 public class KlasaPoboczna
    {
        private KlasaPoboczna() { Console.WriteLine("created"); }
        public void write() { Console.WriteLine("woohho"); }

    }
    public class GlownaKlasa
    {
        public GlownaKlasa() { }
        public KlasaPoboczna Zwroc()
        {
            Type t = typeof(KlasaPoboczna);
            ConstructorInfo[] ci = t.GetConstructors(BindingFlags.Public | BindingFlags.Static |
            BindingFlags.NonPublic | BindingFlags.Instance);
            Object o = ci[0].Invoke(new object[] { });
            KlasaPoboczna k = (KlasaPoboczna)o;
            return k;
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            new GlownaKlasa().Zwroc().write();
            //new KlasaPoboczna().write(); - No can do :)
            Console.ReadKey();
        }
    }

Jak widać z Reflection da się oszukać modyfikatory dostępu ale o ile się nie mylę to internal przy typie w osobnym assembly ( np w dllce ) już sprawi więcej problemów.

0

W sumie to można zapisać równie dobże:

 
0

Whops, enterło mi się ;)

public KlasaPoboczna Zwroc()
{
    return (KlasaPoboczna)typeof(KlasaPoboczna).GetConstructors(BindingFlags.NonPublic | BindingFlags.Instance)[0].Invoke(new object[] { });
}
0

E tam. ;)

public class GlownaKlasa
{
    public KlasaPoboczna Zwroc()
    {
        return new KlasaPoboczna();
    }
}

public class KlasaPoboczna
{
    public KlasaPoboczna()
    {
        var frames = new StackTrace().GetFrames();
        if (frames.Length > 2 && frames[1].GetMethod().ReflectedType != typeof(GlownaKlasa))
        {
            throw new ApplicationException("Nie możesz ręcznie tworzyć obiektów typu KlasaPoboczna");
        }
    }
} 

A tak w ogóle, to po co to? ;P

0

O! Żeby podejść do tego z tej strony to nie pomyślałem.
I ponawiam, po co to? Bo nie mogę wymyślić po co :x

0

Huh, widzę, że to nie takie proste jak myślałem :D Potrzebne mi było po to, że chciałem wymusić używanie tej metody Zwroc() zamiast tworzenia obiektu z KlasaPoboczna 'ręcznie' w kodzie. Anyway dzięki za odpowiedzi :)

0
nameuser napisał(a)

Potrzebne mi było po to, że chciałem wymusić używanie tej metody Zwroc() zamiast tworzenia obiektu z KlasaPoboczna 'ręcznie' w kodzie. Anyway dzięki za odpowiedzi :)

To wiemy, ale nadal nie wiemy po co? Bo może jest prostsze i łatwiejsze rozwiązanie.

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