Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Общие вопросы по .NET и C# > Доступ к объекту другого класса


Автор: Буратиныч 20.6.2013, 16:32
Как получить доступ к объекту другого класса? В данном примере к уже созданной и пополняемой из разных мест программы коллекции mylist_  ?

Код

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            List<string> mylist_1 = new List<string>();
        }
        List<string> mylist_2 = new List<string>();
    }


    class MyClass
    {
         mylist_ ???
        Program prg = new Program();
        
    }
}

Автор: vrann 20.6.2013, 17:28
Если я правильно понял попрос, тебе нужно получить доступ к переменным mylist_1 и mylist_2.

Самое простое решение дать доступ к переменным mylist, объявив их как public.

Выглядеть будет так:

namespace ConsoleApplication1
{
    class Program
    {
        public List<string> mylist_1;
        public List<string> mylist_2;

        static void Main(string[] args)
        {
            mylist_1 = new List<string>();
        }
        mylist_2 = new List<string>();
    }
    class MyClass
    {         
        Program prg = new Program();
         prg.mylist_1 - обращение к первой переменной. Аналогично можно обратиться ко второй
        
    }
}

Автор: Буратиныч 20.6.2013, 17:41
Почему то не хочет создаваться экземпляр prg, да и коллекции тоже не обнаруживаются из класса MyClass.

Задача в целом такая: обращаться к коллекции из любого места программы, в т.ч. и при создании и использовании экземпляра класса.

Автор: vrann 20.6.2013, 18:16
Так, я ошибся немного. 
Смотри. Метод static void Main(string[] args) является рулящим твоей прогой в данный момент. Т.е. если ты хочешь использовать класс MyClass, объявлять его нужно именно в этом методе, а не наоборот. А вот колекции ты можешь загнать в используемый класс. Вот так например:
Код

namespace ConsoleApplication2
{
    class Program
    { 
        static void Main(string[] args)
        {            
            MyClass my = new MyClass();
            //my.mylist_1 - обращение
        }        
    }

    class MyClass
    {
        public List<string> mylist_1;
        public List<string> mylist_2;

        public MyClass()
        {
            mylist_1 = new List<string>();
            mylist_2 = new List<string>();
        }
    }
}

Автор: Буратиныч 20.6.2013, 18:28
А можно ли из рулиемого класса обратиться к рулящему?

Код

namespace ConsoleApplication2
{
    class Program
    {
        static void Main(string[] args)
        {
            MyClass my = new MyClass();
            my.mylist_1.Add("hello");

            MyAnotherClass mac = new MyAnotherClass();
        }
    }

    class MyClass
    {
        public List<string> mylist_1;

        public MyClass()
        {
            mylist_1 = new List<string>();
        }
    }

    class MyAnotherClass
    {
        my.mylist_1.Add("world");   !!!!!!! ошибка
    }
}

Автор: Экскалупатор 20.6.2013, 18:46
Цитата(Буратиныч @  20.6.2013,  17:28 Найти цитируемый пост)
А можно ли из рулиемого класса обратиться к рулящему?

можно все, но всегда нужно сначала хорошенько подумать зачем это делать. то что ты хочешь это какое то извращение, и, как мне кажется, это попытка прикрутить костыли для решения какой то вполне тривиальной задачи. опиши задачу полнее.

а то что тебе хочется можно реализовать через статические классы или статические поля какого то класса. Можно еще синглтон покурить, тож может помочь.

Автор: Буратиныч 20.6.2013, 18:56
Что такое синглтон? Попробовал через статику, но увы

Код

namespace ConsoleApplication2
{
    class Program
    {
        private static List<string> mylist; 
        static void Main(string[] args)
        {
            mylist = new List<string>();
            mylist.Add("hello");
        }
    }

    class MyAnotherClass
    {
        mylist.Add("world");   !!!!!!! ошибка
    }
}


Не знаю какую альтернативу можно придумать. Просто пытаюсь обратиться к члену вне класса при инициализации.

Добавлено через 11 минут и 33 секунды
Пока я вижу только вариант отправлять лист для наполнения в тот или иной метод по ссылке ref. Но это же ведь его надо везде указывать в аргументах. Не очень удобно, по-моему.

Добавлено через 13 минут и 33 секунды
Короче, это коллекция для логов, которая собирает инфу о том, что происходит в разных уголках программы.

Автор: Экскалупатор 20.6.2013, 19:54
Цитата(Буратиныч @  20.6.2013,  17:56 Найти цитируемый пост)
Попробовал через статику, но увы

Код

    class Program
    {
       public static List<string> mylist = new List<string>();; //должен быть открытым
        static void Main(string[] args)
        {
            Program.mylist.Add("hello");
        }
    }

//обращаться так:
    class MyAnotherClass
    {
public void DoSomesing()
{
        Program.mylist.Add("world");   //че то добавляем
    }


надо подучить модификаторы доступа...

Добавлено @ 19:55
https://ru.wikipedia.org/wiki/%D0%9E%D0%B4%D0%B8%D0%BD%D0%BE%D1%87%D0%BA%D0%B0_%28%D1%88%D0%B0%D0%B1%D0%BB%D0%BE%D0%BD_%D0%BF%D1%80%D0%BE%D0%B5%D0%BA%D1%82%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D1%8F%29

Добавлено @ 19:58
Цитата(Буратиныч @  20.6.2013,  17:56 Найти цитируемый пост)
Короче, это коллекция для логов, которая собирает инфу о том, что происходит в разных уголках программы. 

    не стоит изобретать велосипед в этом вопросе. все уже давно изобретено. к примеру log4net уже дает весь требуемый функционал, и дает кучу всяких плюшек, к примеру, формат записи в лог или сохранение в файл/базу

Автор: Буратиныч 20.6.2013, 20:38
cool!  smile 
Имеет ли только смысл выносить переменную в отдельный класс с модификатором статик?

Код

    static class Stat
    {
        public static List<string> mylist = new List<string>();
        
    }

Автор: Экскалупатор 20.6.2013, 20:46
надо делить не по переменным, а по смыслу, т.е. поле должно быть объявлено в том классе в котором оно должно находится логически. если мы говорим про логирование и оно должно быть везде, то очевидно кроме собственно коллекции еще понадобятся методы для обработки этой коллекции, типа сохранние куда нибудь, или рассылка уведомлений, а значит лучше все это вынести как минимум в отдельный класс(ы), а скорее всего может быть даже в отдельный проект, со своей конфигурацией и иерархией. Но все это зависит от масштабов проекта.

P.S. повторюсь, лучше взять готовый модуль для логирования, иначе может возникнуть много проблем, особенно с параллельной обработкой этой коллекции.

Автор: dzaraev 28.6.2013, 20:20
Буратиныч, поймите правильно - вам стоит почитать про основы языка, на котором вы собираетесь писать: http://msdn.microsoft.com/ru-ru/library/zkxk2fwf(v=vs.90).aspx
Экскалупатор, наверное пока нет особого смысла грузить человека log4net'ами и синглтонами, т.к. для начала неплохо бы разобраться в статическом контексте вообще. 

По поводу самого вопроса:
Цитата(Буратиныч @  20.6.2013,  18:56 Найти цитируемый пост)
Короче, это коллекция для логов, которая собирает инфу о том, что происходит в разных уголках программы. 

Значит, вам просто нужен простейший список лог-сообщений. В простейшем случае можно сделать так:


Код

namespace ConsoleApplication2 {
    internal class Program {
        private static void Main(string[] args) {
            MyAnotherClass workClass = new MyAnotherClass();
            workClass.DoWork();
        }
    }

    internal class MyAnotherClass {
        public void DoWork() {
            MyLog.Write("Работа сделана!");
        }
    }

    //если мы хотим использовать лог в других сборках - необходимо сделать класс публичным
    public static class MyLog {
        private static List<string> logMessages = new List<string>();

        public static void Write(string message) {
            logMessages.Add(message);
            //также здесь можно добавить код записи лога в файл, например
        }
    }
}


То, что вы пишете
Цитата

Задача в целом такая: обращаться к коллекции из любого места программы

как правило реализуется в конечном итоге за счет статических членов, т.к. тип (ваш класс) доступен из любого места программы, где он виден, а вот для обращения к экземпляру необходима ссылка на него(на экземпляр класса).

и далее
Цитата

, в т.ч. и при создании и использовании экземпляра класса. 

вот это требование немного не понял, если что - уточните, попробую ответить.

Автор: Буратиныч 28.6.2013, 20:39
В целом со статикой я разобрался, всем спасибо! Но остался подвешенным вопрос, если я пишу под WPF как я могу из объекта какого-либо класса обратиться к членам входного класса, т.е public partial class MainWindow : Window ?

Автор: dzaraev 28.6.2013, 21:40
Цитата(Буратиныч @  28.6.2013,  20:39 Найти цитируемый пост)
 обратиться к членам входного класса

Что вы имеете в виду под "входным классом" ? Если имеется в виду базовый класс (т.е. тот, от которого наследуется ваш класс),
то вы можете из вашего класса обращаться к тем членам базового класса, которые помечены http://msdn.microsoft.com/ru-ru/library/wxh6fsc7(v=vs.100).aspx public, protected или protected internal. 

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)