Задать вопрос
des1roer
@des1roer
ученье - свет, а неученье - приятный полумрак

C# вернуть массив из класса?

решил переписать в ооп стиле
public class DbConfig
        {
            public class DbConf
            {
                public string Server;
                public string Port;
                public string User;
                public string Pass;
                public string Db;
            }

            public static List<DbConf> GetDbConf()
            {
                try
                {
                    var list = new List<DbConf>();
                    var m_strFilePath = Properties.Settings.Default.http_path;
                    string xmlStr;
                    XmlDocument xml = new XmlDocument();    //xml

                    using (var wc = new WebClient())
                    {
                        xmlStr = wc.DownloadString(m_strFilePath);
                    }
                    var xmlDoc = new XmlDocument();
                    xml.LoadXml(xmlStr);

                    foreach (XmlNode n in xml.SelectNodes(Properties.Settings.Default.setting_node))
                    {
                        list.Add(new DbConf
                        {
                            Server = n.SelectSingleNode("server").InnerText,
                            Port = n.SelectSingleNode("port").InnerText,
                            User = n.SelectSingleNode("user_id").InnerText,
                            Pass = n.SelectSingleNode("password").InnerText,
                            Db = n.SelectSingleNode("database").InnerText
                        });
                    };
                    return list;
                }
                catch (Exception msg)
                {
                    logger.Debug(msg);
                    return null;
                }
            }
        }

так
public MainWork()
        {
            foreach (var c in DbConfig.GetDbConf())
            {
                Console.WriteLine("{0} {1}", c.Server, c.Port);
            }
        }

работает.

но как мне обратиться из любого места программы к данным?
var c = DbConfig.GetDbConf();
            Console.WriteLine("{0} {1}", c.Server, c.Port);
  • Вопрос задан
  • 995 просмотров
Подписаться 1 Оценить Комментировать
Пригласить эксперта
Ответы на вопрос 3
lexxpavlov
@lexxpavlov
Программист, преподаватель
Во-первых, не нужно пересоздавать список в цикле. Вы уже создали список в начале метода - вот его и используйте, иначе в каждом найденном элементе xml-документа затираются ранее найденные элементы (разве что вы так и хотите сделать, и то - лучше сделать это по другому). Уберите list = new List(); в цикле.

Во-вторых, вы уверены, что "Ссылка на объект не указывает на экземпляр объекта" - проблема с DbConf[0], а не с logger? Или, скорее, проблема в самом методе. Например, в n.SelectSingleNode("server").InnerText - и правда есть элемент "server"?. Потому что этот код метода выглядит как правильный.
Поставьте брейкпоинт в метод, и посмотрите по шагам, где именно возникает исключение.

Ну и в-третьих, названия методов принято называть, начиная с глагола. Метод (функция) - это действие с данным, а не данные. Назовите метод ReadXml().

UPD.
но как мне обратиться из любого места программы к данным?

Сколько у вас конфигов? Больше одного? ведь у вас список, значит, нужно выбирать конкретный конфиг:

var configs = DbConfig.GetDbConf();
Console.WriteLine("{0} {1}", c[0].Server, c[0].Port);


А если вы знаете имя сервера, то используйте словарь вместо списка:
public static Dictionary<string, DbConf> GetDbConf()
{
	try
	{
		var configs = new Dictionary<string, DbConf>();
		
		// ...

		foreach (XmlNode n in xml.SelectNodes(Properties.Settings.Default.setting_node))
		{
			string server = n.SelectSingleNode("server").InnerText;
			configs.Add(server, new DbConf
			{
				Server = server,
				Port = n.SelectSingleNode("port").InnerText,
				User = n.SelectSingleNode("user_id").InnerText,
				Pass = n.SelectSingleNode("password").InnerText,
				Db = n.SelectSingleNode("database").InnerText
			});
		};
		return list;
	}
	catch (Exception msg)
	{
		logger.Debug(msg);
		return null;
	}
}

var configs = DbConfig.GetDbConf();
var serverName = "localhost";
var config = configs[serverName];
Console.WriteLine("{0} {1}", config.Server, config.Port);


И сделайте в классе более типизированные поля - Port и User можно сделать int (тогда уж не User, а UserId).
Ответ написан
Комментировать
@MonkAlex
C#, SQL, Delphi, C++ etc
Ссылка на объект не указывает на экземпляр объекта.
Обычно стек указывает ещё и строчку, в которой возникло исключение. А по строчке уже легче понять, какой именно объект оказался недоступен.
ПС: или можно в отладке запустить, тогда студия явно выкинет сообщение с элемента, который недоступен.

UPD: при исключении возвращать null конечно можно, но foreach тогда упадёт. Если чтение конфига - ситуация обязательная, то это в принципе допустимо, но тогда лучше уж не ловить исключение при чтении. А если конфиг может и не загружаться в каких то случаях - то тогда лучше вернуть пустой list, чтобы foreach не падал.
Ответ написан
Комментировать
yarosroman
@yarosroman Куратор тега C#
C# the best
>>но как мне обратиться из любого места программы к данным?
Сделать Singleton
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы