1 Востаннє редагувалося getwisdom (27.12.2015 19:47:31)

Тема: Class hierarchy.

Для прикладу у мене є класс:

class ExampleClass
{
    protected string key = "some hidden value";
}

Також є класс котрому потрібно доступитись до значення key вищеописаного класу,проте інші класи не повинні мати доступу до поля key.

class PoorClass
{
//Some realization.Anyway now i need to access (object of ExampleClass).key ,but it is protected.
}


Класс

class PoorClass

повинен і лише він повинен,окрім звісно

class ExampleClass

мати доступ до поля

protected string key

Можна звісно ж просто унаслідувати класс PoorClass з ExampleClass:

class PoorClass : ExampleClass

Проте обидва класи логічно ніяк не пов'язані зовсім.Що робити тоді?
http://stackoverflow.com/questions/3448 … apsulation

2

Re: Class hierarchy.

робіть рефлексію

Подякували: getwisdom, leofun012

3 Востаннє редагувалося getwisdom (27.12.2015 21:52:17)

Re: Class hierarchy.

FakiNyan написав:

робіть рефлексію

Дякую.
Вперше з таким зіткнувся.
Можливо комусь буде цікаво як можна доступатись до private та protected members класу.Чесно кажучи не думав,що це так просто.
https://msdn.microsoft.com/uk-ua/library/ms173183.aspx
http://stackoverflow.com/questions/1086 … ate-fields
http://stackoverflow.com/questions/9591 … reflection

using System.Reflection
  class Program
    {
        static void Main(string[] args)
        {
            PoorClase objPoorClase = new PoorClase();
            Console.ReadLine();
        }
    }
    class ExampleClass
    {
        protected string key = "some hidden value";
    }
    class PoorClase
    {
        public PoorClase()
        {
            ExampleClass objExampleClass = new ExampleClass();
            Type t = typeof(ExampleClass);
            FieldInfo[] tArray = t.GetFields(BindingFlags.NonPublic | BindingFlags.GetField | BindingFlags.Instance);
            foreach (FieldInfo info in tArray)
            {
                Console.WriteLine(info.Name);
                Console.WriteLine(info.GetValue(objExampleClass));
            }
        }
    }
Подякували: DOP, leofun012

4

Re: Class hierarchy.

Рефлексія - це крайній засіб, бо вона дуже дорога за ресурсами. Давайте спробуємо розібратися спершу, чому вам потрібна саме така схема доступу до даних. Ви не кажете, що це за класи; але очевидно, що PoorClase має якийсь безпосередній стосунок до ExampleClass. Дуже тісний. Настільки тісний, що є його частиною. Ну то так і робимо:

class ExampleClass {
    protected string key = "some hidden value";

    public class PoorClase {
        public PoorClase(ExampleClass e) {
            Console.WriteLine(e.key);
        }
    }
}
public class Program
{
    public static void Main() {
        ExampleClass.PoorClase p = new ExampleClass.PoorClase( new ExampleClass() );
    }
}

І все - жодних рефлексій.

Подякували: getwisdom, leofun012

5

Re: Class hierarchy.

koala написав:

Рефлексія - це крайній засіб, бо вона дуже дорога за ресурсами. Давайте спробуємо розібратися спершу, чому вам потрібна саме така схема доступу до даних. Ви не кажете, що це за класи; але очевидно, що PoorClase має якийсь безпосередній стосунок до ExampleClass. Дуже тісний. Настільки тісний, що є його частиною. Ну то так і робимо:

class ExampleClass {
    protected string key = "some hidden value";

    public class PoorClase {
        public PoorClase(ExampleClass e) {
            Console.WriteLine(e.key);
        }
    }
}
public class Program
{
    public static void Main() {
        ExampleClass.PoorClase p = new ExampleClass.PoorClase( new ExampleClass() );
    }
}

І все - жодних рефлексій.

Розібравшись більш-менш з C#core я вирішив написати елементарну консольну гру Hangman використовуючи ООП принцип.
https://en.wikipedia.org/wiki/Hangman_(game)
В мене є три типи:Player,WordsContainer та Game.
Спершу ідея виглядала так.Я описую клас Player.

namespace Hangman
{
    class Player
    {
        /// <summary>
        /// class Player consist fields: player name,amount of lives, amount of game points and bool variable 
        /// which represents is current player alive or not.
        /// Class methods consist constructors and showPlayerInfo methods.
        /// </summary>
        public string name { get; set; }
        public int livesAmount { get; private set; }
        public int pointsAmount { get; private set; }
        protected bool playerIsAlive = true;
        public bool isAlive
        {
            get { return playerIsAlive; }
            set { playerIsAlive = (this.livesAmount > 0) ? true : false; }
        }
        public Player():this("NoName",0,3) {}
        public Player(string name):this(name,0,3) {}
        protected Player(string name,int pointsAmount,int livesAmount = 3)
        {
            this.name = name;
            this.livesAmount = livesAmount;
            this.pointsAmount = pointsAmount;
        }
        public void ShowPlayerInfo()
        {
            if (playerIsAlive)
                Console.WriteLine("{0} player has {1} points and {2} lives amount.", name, pointsAmount, livesAmount);
            else
                Console.WriteLine("{0} player get {1} game points,well played.", name, pointsAmount);
        }
       
    }
}

Тоді реалізую контейнер котрий містить список слів і містить метод public string getKeyWord().

namespace Hangman
{
    class WordsContainer
    {
        /// <summary>
        /// WordsContainer class contains a list of strings from wich with getKeyWord method
        /// we could get string type key.
        /// </summary>
        private List<string> wordBank = new List<string>() {"stack","queue","heap","git","array"};
        public WordsContainer(){}
        public string getKeyWord()
        {
            Random random = new Random((int)DateTime.Now.Ticks);

            return wordBank[random.Next(0, wordBank.Count)];
        }
        
    }
}

Ну а вже клас Game повинен був би містити в собі об'єкт типу Player та об'єкт типу WordsContainer.Тут я подумав,що хотів би приховати метод  public string getKeyWord() від усіх інших класів окрім самого class WordsContainer та Game.З Вашою ієрархією

class ExampleClass {
    protected string key = "some hidden value";
 
    public class PoorClase {
        public PoorClase(ExampleClass e) {
            Console.WriteLine(e.key);
        }
    }
}

мій клас WordsContainer міститиме клас Game,що як в моєму випадку не логічно.
Виклав теж саме питання на SO:

http://stackoverflow.com/questions/3448 … apsulation

6

Re: Class hierarchy.

Тут я подумав,що хотів би приховати метод  public string getKeyWord() від усіх інших класів окрім самого class WordsContainer та Game.

Нащо? Приховувати треба внутрішню реалізацію, а не інтерфейс. А раз ви хочете викликати цей метод ззовні, то це інтерфейс. Захочете потім зробити якусь "Балду", то цей клас з публічним методом буде вам в нагоді (якщо слова не будуть забиті в коді намертво, звичайно ж).

Подякували: getwisdom, koala2

7 Востаннє редагувалося getwisdom (28.12.2015 23:13:24)

Re: Class hierarchy.

Дякую.

8

Re: Class hierarchy.

Чи я не зовсім розібрався в запитання чи ще щось, але якщо тут говорять про інтерфейси класів, і що клас має комусь щось надавати, а комусь ні, то чому цей клас не успадкувати від кількох (двох) інтерфейсів і передавати іншим класам ці інтерфейси?

interface IKeyWordsProvider
{
    void getKeyWord();
}

class WordsContainer : IKeyWordsProvider
{
    void getKeyWord()
    {
    }
}

9 Востаннє редагувалося Yola (07.01.2016 13:16:49)

Re: Class hierarchy.

Або

class WordsContainer : IEnumerable<String>
{
    private List<string> wordBank = new List<String>() {"stack","queue","heap","git","array"};

    public IEnumerator<String> GetEnumerator()
    {
         while (true)
        {
            Random random = new Random((int)DateTime.Now.Ticks);
            yield return wordBank[random.Next(0, wordBank.Count)];
        }
    }

    System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
    {
        return this.GetEnumerator();
    }
}

І використати так

WordsContainer wc;
IEnumerable<String> e = wc;
foreach (String word in e)
{
     PlayWith(word);
     if (!wantMore)
          break;
}

Зречення: давно на C# не писав, можуть бути грубі помилки.

Подякували: getwisdom, leofun012