D
D
des1roer2015-11-25 08:08:52
C++ / C#
des1roer, 2015-11-25 08:08:52

C# return array from class?

decided to rewrite in oop style

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;
                }
            }
        }

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

works.
but how can I access the data from anywhere in the program?
var c = DbConfig.GetDbConf();
            Console.WriteLine("{0} {1}", c.Server, c.Port);

Answer the question

In order to leave comments, you need to log in

3 answer(s)
A
Alexey Pavlov, 2015-11-25
@lexxpavlov

First, there is no need to recreate the list in a loop. You have already created a list at the beginning of the method - so use it, otherwise, in each found element of the xml document, the previously found elements are overwritten (unless you want to do this, and then it’s better to do it differently). Remove list = new List(); in a cycle.
Second, are you sure "Object reference does not point to an instance of an object" is a problem with DbConf[0] and not with logger? Or rather, the problem is in the method itself. For example, in n.SelectSingleNode("server").InnerText - is there really a "server" element? Because this method code looks like the right one.
Put a breakpoint in the method and see step by step where exactly the exception occurs.
And thirdly, it is customary to name the names of methods, starting with the verb. A method (function) is an action with data, not data. Name the method ReadXml().
How many configs do you have? More than one? because you have a list, which means you need to select a specific config:

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

And if you know the server name, then use a dictionary instead of a list:
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);

And make more typed fields in the class - Port and User can be made int (then not User, but UserId).

M
MonkAlex, 2015-11-25
@MonkAlex

An object reference does not point to an instance of an object.
Typically, the stack also indicates the line at which the exception occurred. And by the line it is already easier to understand which object was unavailable.
PS: or you can run it in debugging, then the studio will explicitly throw out a message from an element that is not available.
UPD: it is certainly possible to return null in case of an exception, but then foreach will fall. If reading the config is a mandatory situation, then this is in principle acceptable, but then it's better not to catch an exception when reading. And if the config may not be loaded in some cases, then it is better to return an empty list so that foreach does not crash.

R
Roman, 2015-11-25
@yarosroman

>> but how can I access the data from anywhere in the program?
Make Singleton

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question