I am reading connection strings from my App.config file and for that i have following code.
try
{
string[] dbnames;
int counter = 0;
foreach (ConnectionStringSettings connSettings in ConfigurationManager.ConnectionStrings)
{
dbnames[counter] = connSettings.Name;
counter++;
}
return dbnames;
}
catch
{
throw;
}
this code giving me error use of unassigned local variable for dbnames. i will have multiple connection strings in my App.config. They can be none,1,2 and so on. Depending on the needs. so i cant statically assign the dbname size. Because there can be a scenario if they exceed the value of assigned size. eg. if i assign it a size of 5, and what if i get 6th connection string. and if i have 1, then remaining 4 will be a memory wastage.
If i am wrong then let me know.
Thanks.
Use this while initializing the array.
string[] dbnames = new string[ConfigurationManager.ConnectionStrings.Count];
OR use List<string>
You can't resize a System.Array dynamically like that.
Fortunately, there's no reason to do so. Use a different type of collection, like a List<T> instead. (Make sure you've added a using declaration for the System.Collections.Generic namespace!)
Like an array, a List<T> allows you to access the elements in the list by index, but it's also dynamically resizable at run-time, which fulfills the requirements in your question. And of course, since it's a generic method, it has the additional advantage (as compared to some of your other choices) of being strongly-typed. Since you're working with string types, you would use List<string>.
EDIT: There's absolutely no need for that empty try/catch block. Why catch an exception if you're just going to immediately rethow it? Just let it bubble up. In general, you shouldn't catch exceptions unless and only unless you can fix their immediate cause.
You're declaring dbnames as a string array, but not defining it's size.
You'll need something like:
string[] dbames = new string[4];
where "4" is the length of your array.
If, however, you need a variable length you should use List<string>. In this case you can then add to it as necessary.
As others have said, you could just use a List<string>. I would use LINQ to do all of this though, if you're using .NET 3.5 or higher:
return ConfigurationManager.ConnectionStrings
.Cast<ConnectionStringSettings>()
.Select(setting => setting.Name)
.ToArray(); // Or ToList
No need for a foreach loop (in your code - obviously it's there somewher :)
You can easily decide whether to return a list, an array, or simply IEnumerable<string>
No need for try/catch
declare it after class
e.g
i am also writing code and i used to always encounter this problem
public class ABC{
string[] array;
ABC()
{
}
//your_function_logics
}
Related
basically I'm trying to append something to an array, but for some reason in wont even work.
(gObject is a thing with a name and a value)
public gObject[] OBJECTS = {};
public void RegisterObjectToRender(gObject reg)
{
OBJECTS.Append<gObject>(reg);
for (int ri = 0; ri < OBJECTS.Length; ri++)
{
Console.WriteLine(OBJECTS[ri].Name);
}
}
I hope everyone who is reading this is having a good day btw
Arrays are fixed size, always. If you want a list: use a list, i.e. use List<Your type> instead of an array. A list has an Add method.
I'm guessing the Append method here is a local extension method that only exists in your code (that isn't a normal API). I'm also guessing that it calls Array.Resize internally, but: that creates a new and different array - it doesn't change the existing array. So if you use that, you'd need to swap the underlying reference afterwards, too - to the new array reference. However, don't do that: Array.Resize is incredibly inefficient, as it allocates a new array every append (contrast List<T> which keeps an oversized backing array, and tracks the count separately, only increasing the underlying array occasionally).
Append returns a new IEnumerable. It does not add to the OBJECTS, but essentially returns a new list. You have to capture the result of Append and use that: var extendedList = OBJECTS.Append(reg).
A better way is to use a list and use Add instead of Append. It is faster and cleaner.
I know that the method is returning List<string> at the moment. But in some (which occur quite frequently in our application) scenarios, it returns List having only one string.
So eventually it would return either string or List<string>.
Since it's unpredictable what it'll return at run time, at present it's return type is kept as object.
What alternative approach could be used to avoid method returning object?
EDIT:
I would like to have answer to the question What alternative approach could be used to avoid method returning object? ; without considering the scenario I described. List is enough here.
why return a string? a List<string> with a single string in it is perfectly well defined... use that! An ambiguous API is silly here.
Another option might be IEnumerable<string>, but... meh, just return the list with a single string!
Return a List that contains one or more string elements, and process the list as a list regardless of the number of elements it contains.
There is no problem to have a List with one and more and even with no string(empty list).
Why you want to have string when there is only one element in the List.
Just keep the API more clear.
I dont see the the problem of returning List<string> even the List contain only one element. But if you really want your method to behave differently with one string value, you could do
public List<string> GetStrList(out string val)
{
//set str = string.Empty; when value is more than one
//set str = whateverstring when value is only one
}
Hmm, does this method perhaps call 2 different methods inside its body, one returning a string and one returning a List<string>? If so, maybe you could change your method to return an IEnumerable<string>, and change the return GetSingleString(); statement to yield returnGetSingleString();
Or you could add it to a list with a single element and return the list, like some of the other answers suggest here
I guess it's rather stupid question.
I want to pass an array argument to method by value, not by link, i.e. I want to make a copy of object to prevent changing of argument inside the method.
Thanks in advance.
If your method acts destructively on its parameter's contents, simply make a copy of the array inside the method.
This is as simple as
var copy = parameter.ToArray();
if you are using LINQ, otherwise it can also be done easily with Array.Copy.
This is much better than copying before calling the method (as you mention in the question), because you can always forget to do that. Copying inside the method leaves no possibility of error.
Arrays are reference types. You can't have them automatically be cloned when passed to a method.
You have to make a clone manually and pass the resulting array to the method:
int[] array = ...
MyMethod((int[])array.Clone());
Note that this is an O(n) operation can can be quite slow for large arrays or many repeated calls.
There is no way to do this in C#. You will need to copy the array yourself, either inside the method, or on the calling side:
int[] array = GetIntArray();
CallSomeMethod(array.ToArray()); // ToArray() makes a copy of the input...
My understanding of the question in the OP is the poster is looking for a way to pass a reference type by value. I found this example:
class PassingRefByVal
{
static void Change(int[] arr)
{
//arr[0]=888; // This change affects the original element.
arr = new int[5] {-3, -1, -2, -3, -4}; // This change is local.
Console.WriteLine("Inside the method, the first element is: {0}", arr[0]);
}
public static void Main()
{
int[] myArray = {1,4,5};
Console.WriteLine("Inside Main, before calling the method, the first element is: {0}", myArray [0]);
Change(myArray);
Console.WriteLine("Inside Main, after calling the method, the first element is: {0}", myArray [0]);
Console.ReadLine();
}
}
here: http://msdn.microsoft.com/en-us/library/0f66670z(v=vs.71).aspx
Hope this is what you're looking for.
Friends, I must create a series of ArrayLists, each containing objects of unknown origin, with each instance assigned to a separate local variable.
So far, so good... But I also need each local variable's name to follow a very specific pattern: the name should begin with "oArr", followed by one or more digits reflecting that particular array's position within the sequence. Furthermore, I will not know at compile-time how many of these arrays - and hence, how many local variables - I will be needing!
It strikes me that this is perhaps a problem that could be solved by the availability of dynamic types in C# 4.0, however I am not at all familiar with their use. How might I take code like this...
int i=0;
foreach(something)
{
ArrayList oArr+i=new ArrayList();
i++;
}
...and turn it into something that matches the criteria outlined above and actually compiles?
Alternately, is there a more simple, sane approach to this problem?
You cannot change the name of a variable during execution, since the code (even c# code) was compiled with a certain variable name. If you could change the name during execution then it would cause problems.
For example, if the language allowed to change variable names then when you try to access a variable named 'var1' the compiler has no idea if during execution that variable name changed and now is called 'x'.
Something you could try to do is to allow your program to dynamically compile some code but this is probably not the right solution to your problem. If you explain better what you need then we could provide you with an effective solution.
Hope this helped
EDIT: Seeing your editions I can tell you that it is impossible with the approach you are currently using. I could suggest you the following:
int i = 0;
List<ArrayList> masterList = new List<ArrayList>();
foreach (something)
{
masterList.Add(new ArrayList());
i++;
}
If what you need is to have each ArrayList to have a specific name you can recall you can use a dictionary:
int i = 0;
Dictionary<string, ArrayList> masterList = new Dictionary<string, ArrayList>();
foreach (something)
{
masterList.Add("oArr" + i.ToString(), new ArrayList());
i++;
}
ArrayList al = masterList["oArr1"];
Would this work for you?
var arrayLists = new List<ArrayList>();
var i = 0;
foreach(var item in list)
{
arrayLists.Add(new ArrayList());
i++;
}
Then you can access each array list by index.
Use a List of ArrayLists.
I deal with a framework on a daily basis where we sometimes provide methods that accept IEnumerable<MyBusinessObject> as a parameter in order to show user interfaces, perform calculations etc.
If I pass in an array of MyBusinessObject like so:
MyBusinessObject[] myArray = new MyBusinessObject { obj1, obj2, ..., objN };
frameworkClass.MyMethod(myArray);
....
public class FrameworkClass
{
public void MyMethod(IEnumerable<MyBusinessObject> objs)
{
// Other code that uses the enumerable
MyBusinessObject[] objectArray = objs.ToArray();
// More code that uses the enumerable
}
}
Does the line objs.ToArray() simply resolve the IEnumerable<MyBusinessObject> back to the original array, or does it copy it to a whole new array, ready for use?
No, you will always get a new copy of the array, though the objects in it aren't copies, they are the same references as in the original array.
It would be very inconsistent for changes to the returned array to sometimes affect the source and sometimes not. ToList works the same way for the same reason.
You can check source code (as of 2015) if you need to review details: Enumerable.ToArray which in turn creates copy of elements (optimized for ICollection and hence Array[], but still making copy) with internal Buffer class.
You will get a new copy of the array if there is one or more element in it. For empty arrays, you might get the same array back, at least in .NET 5:
Console.WriteLine(Object.ReferenceEquals(Array.Empty<string>(), Array.Empty<string>().ToArray()));
This returns true.