C# - check if List<> is initialized - c#

I have function that accept out List<int> list as parameter. How can I check if list is initialized or not?
This code gives me the Use of unassigned out parameter 'list' error:
public void CheckList(out List<int> list)
{
if (list == null) {
list = List<int>();
}
//Rest of the code
}
Facts that I have checked:
Variables passed as out arguments do not have to be initialized before being passed in a method call. However, the called method is
required to assign a value before the method returns. out parameter
modifier
Edit:
I want my method to be able to accept both options: list with elemtns and append aditional elements to it or in other case to initialize list and add elements to it.

If you are dealing with out argument then most certainly it isn't initialized because the method should initialize it.
If it was passed by "ref", then you would check it.

Why not use a wrapper?
public void CheckListWrapper(ref List<int> list)
{
if(list == null)
{
CheckList(out list);
}
else
{
//append whatever
}
}
public void CheckList(out List<int> list)
{
list = List<int>();
//Rest of the code
}

I added a new parameter for sameList and it will work for you so
what about this one. There is no more way to accept without Initialization.
private static void Main()
{
List<int> i=null;
CheckList(out i,i);
Console.WriteLine(i[0]);
}
public static void CheckList(out List<int> list,List<int> sameList)
{
list = sameList;
if(list==null)
{
//Intialize
list = new List<int>();
list.Add(1);
}
else
{
//append
list.Add(12);
}
//Rest of the code
}

Try the following code:
bool IsInitialised(List myList) {
if ( (myList!= null) && (!myList.Any()) )
{
return true;
}
return false;
}
A linq-less way will be:
if(myList != null && myList.Count == 0){
// The list is empty. Add something here
}
From your calling method like Main:
Pseudo code. Testmethod(ref list) and TestMethod(list) have different signature so they both compile.
if(IsInitialised(list))
Call TestMethod(ref list);
Else call TestMethod(list);

Related

Confused about IEnumerator interface

I am trying to understand how to use the IEnumerator interface and what it is used for. I have a class which implements the IEnumerator interface. A string array is passed to the constructor method.
The problem is when I execute the code then the array is not listed properly. It should be doing it in the order "ali", "veli", "hatca" but it’s listed at the console in this order "veli", "hatca" and -1. I am so confused. What am I doing wrong here? Can you please help?
static void Main(string[] args)
{
ogr o = new ogr();
while (o.MoveNext())
{
Console.WriteLine(o.Current.ToString());
}
}
public class ogr: IEnumerator
{
ArrayList array_ = new ArrayList();
string[] names = new string[] {
"ali", "veli", "hatca"
};
public ogr()
{
array_.AddRange(names);
}
public void addOgr(string name)
{
array_.Add(name);
}
int position;
public object Current
{
get
{
if (position >= 0 && position < array_.Count)
{
return array_[position];
}
else
{
return -1;
}
}
}
public bool MoveNext()
{
if (position < array_.Count && position >= 0)
{
position++;
return true;
}
else
{
return false;
}
}
public void Reset()
{
position = 0;
}
}
IEnumerator is quite difficult to grasp at first, but luckily it's an interface you hardly ever use in itself. Instead, you should probably implement IEnumerable<T>.
However, the source of your confusion comes from this line from the IEnumerator documentation:
Initially, the enumerator is positioned before the first element in
the collection. The Reset method also brings the enumerator back to
this position. After an enumerator is created or the Reset method is
called, you must call the MoveNext method to advance the enumerator to
the first element of the collection before reading the value of
Current; otherwise, Current is undefined.
Your implementation has its current position at 0 initially, instead of -1, causing the strange behavior. Your enumerator begins with Current on the first element instead of being before it.
It is pretty rare for people to use that API directly. More commonly, it is simply used via the foreach statement, i.e.
foreach(var value in someEnumerable) { ... }
where someEnumerable implements IEnumerable, IEnumerable<T> or just the duck-typed pattern. Your class ogr certainly isn't an IEnumerator, and shouldn't be made to try to act like one.
If the intend is for ogr to be enumerable, then:
public ogr : IEnumerable {
IEnumerator IEnumerable.GetEnumerator() {
return array_.GetEnumerator();
}
}
I suspect it would be better to be IEnumerable<string>, though, using List<string> as the backing list:
public SomeType : IEnumerable<string> {
private readonly List<string> someField = new List<string>();
public IEnumerator<string> GetEnumerator()
{ return someField.GetEnumerator(); }
IEnumerator IEnumerable.GetEnumerator()
{ return someField.GetEnumerator(); }
}

How can I avoid code repetition with enums in C#?

I am populating three list boxes with values from three corresponding enums. Is there some way to avoid having three separate-but-very-similar methods? Here's what I have now:
private void PopulateListBoxOne()
{
foreach (EnumOne one in Enum.GetValues(typeof(EnumOne)))
{
lstOne.Items.Add(one);
}
lstOne.SelectedIndex = 0;
}
private void PopulateListBoxTwo()
{
foreach (EnumTwo two in Enum.GetValues(typeof(EnumTwo)))
{
lstTwo.Items.Add(two);
}
lstTwo.SelectedIndex = 0;
}
private void PopulateListBoxThree()
{
foreach (EnumThree three in Enum.GetValues(typeof(EnumThree)))
{
lstThree.Items.Add(three);
}
lstThree.SelectedIndex = 0;
}
But I'd instead prefer to have one method (which I could call three times) looking something like:
private void PopulateListBox(ListBox ListBoxName, Enum EnumName)
{
// ... code here!
}
I'm quite an inexperienced programmer, so although I did search, I wasn't quite sure what I was searching for. Apologies if this has been answered before; I'd be equally grateful to be shown an existing answer. Thanks!
You need to pass enum type to your method
private void PopulateListBox(ListBox ListBoxName, Type EnumType)
{
foreach (var value in Enum.GetValues(EnumType))
{
ListBoxName.Items.Add(value);
}
ListBoxName.SelectedIndex=0;
}
so call it like:
PopulateListBox(lstThree,typeof(EnumThree));
You could use a generic method:
private void PopulateListBox<TEnum>(ListBox listBox, bool clearBeforeFill, int selIndex) where TEnum : struct, IConvertible
{
if (!typeof(TEnum).IsEnum)
throw new ArgumentException("T must be an enum type");
if(clearBeforeFill) listBox.Items.Clear();
listBox.Items.AddRange(Enum.GetNames(typeof(TEnum))); // or listBox.Items.AddRange(Enum.GetValues(typeof(TEnum)).Cast<object>().ToArray());
if(selIndex >= listBox.Items.Count)
throw new ArgumentException("SelectedIndex must be lower than ListBox.Items.Count");
listBox.SelectedIndex = selIndex;
}
How you use it:
PopulateListBox<EnumThree>(lstThree, true, 0);
You could try something like
private List<T> PopulateList<T>()
{
List<T> list = new List<T>();
foreach (T e in Enum.GetValues(typeof(T)))
{
list.Add(e);
}
return list;
}

VS2012 assert helper function - test runner should not track in my function

During testing I have several Assert helper functions specific to the project. For example, I have to often check whether two IEnumerables are equivalent (exactly same content by reference, not regarding the order). So have a static class for these. E.g.:
internal static class MyAssert
{
public static void AreEquivalent<T>(IEnumerable<T> enumerable1, IEnumerable<T> enumerable2)
{
bool val = false;
if (enumerable2 == null)
{
val = !enumerable1.Any();
} else {
var list1 = enumerable1.ToList();
var list2 = enumerable2.ToList();
val = (list1.Count == list2.Count && list1.Intersect(list2).Count() == list2.Count());
}
Assert.IsTrue(val);
}
}
Then if I use MyAssert.AreEquivalent(enumer1, enumer2);, and it fails, then the whole stack trace is shown inside the helper function. I would like to miss it, so if a developer comes, and sees the source of assert, he only sees that the MyAssert thing failed, but he does not see where was the problem inside my helper function (he cannot do anything with Assert.IsTrue(val)).
I know that it can be done with Assert.IsTrue(MyCollHelper.AreEquivalent(enumer1, enumer2)), but this is not as readebly as the previous.
I not sure that I understand you correctly. If you or the developer will see which part of your method causes the error than use Assert.Fail(). I didn't test it:
internal static class MyAssert
{
public static void AreEquivalent<T>(IEnumerable<T> enumerable1, IEnumerable<T> enumerable2)
{
bool val = false;
if (enumerable2 == null)
{
val = !enumerable1.Any();
if (val == false)
{
Assert.Fail("enumerable2 is empty, enumerable1 is not");
}
}
else if (enumerable1 == null)
{
val = !enumerable2.Any();
if (val == false)
{
Assert.Fail("enumerable1 is empty, enumerable2 is not");
}
}
else
{
var list1 = enumerable1.ToList();
var list2 = enumerable2.ToList();
if (list1.Count != list2.Count)
{
Assert.Fail("Count result is not the same");
}
if (list1.Intersect(list2).Count() != list2.Count())
{
Assert.Fail("count of Intersect enumerable1 is not the same as enumerable2 count");
}
}
}
}
Unfortunately this is impossible now.

"Else" equivalent in foreach loop when ienumerable is empty

Assuming the ienumerable is not null, a foreach loop simply won't execute if that ienumerable is empty. But instead, I need to run other code if the collection is empty. Here's sample code which works flawlessly:
List<string> theList = new List<string>() {};
if (theList.Count > 0) {
foreach (var item in theList) {
//do stuff
}
} else {
//throw exception or do whatever else
}
Is there anyway to shorten this up via out-of-the-box C#, an Extension Method, etc? In my head I was thinking the following would be cool, but obviously it doesn't work:
List<string> theList = new List<string>() {};
foreach (var item in theList) {
//do stuff
} else {
//throw exception or do whatever else
}
EDIT: My solution thanks to insight from Maarten: The following will throw an exception if the collection is null or empty (if you want to simply ignore cases where the collection is null or empty, use a ternary operator in the foreach)
static class Extension {
public static IEnumerable<T> FailIfNullOrEmpty<T>(this IEnumerable<T> collection) {
if (collection == null || !collection.Any())
throw new Exception("Collection is null or empty");
return collection;
}
}
class Program {
List<string> theList = new List<string>() { "a" };
foreach (var item in theList.FailIfNullOrEmpty()) {
//do stuff
}
}
If you really wanted to achieve this, you could create an extension method (like you said yourself).
class Program {
static void Main(string[] args) {
List<string> data = new List<string>();
foreach (var item in data.FailIfEmpty(new Exception("List is empty"))) {
// do stuff
}
}
}
public static class Extensions {
public static IEnumerable<T> FailIfEmpty<T>(this IEnumerable<T> collection, Exception exception) {
if (!collection.Any()) {
throw exception;
}
return collection;
}
}
You can throw the exception beforehand, without having to write the else block:
if(mylist.Count == 0)
throw new Exception("Test");
foreach(var currItem in mylist)
currItem.DoStuff();
The execution flow won't reach the loop if the exception has been raised.

How to return a readonly copy of a collection

I have a class that contains a collection. I want to provided a method or property that returns the contents of the collection. It's ok if calling classes can modify the individual objects but I do not want them adding or removing object from the actual collection. I have been copying all the objects to a new list, but now I'm thinking that I could just return the list as IEnumerable<>.
In the simplified example below is GetListC the best way to return a read only version of a collection?
public class MyClass
{
private List<string> mylist;
public MyClass()
{
mylist = new List<string>();
}
public void Add(string toAdd)
{
mylist.Add(toAdd);
}
//Returns the list directly
public List<String> GetListA
{
get
{
return mylist;
}
}
//returns a copy of the list
public List<String> GetListB
{
get
{
List<string> returnList = new List<string>();
foreach (string st in this.mylist)
{
returnList.Add(st);
}
return returnList;
}
}
//Returns the list as IEnumerable
public IEnumerable<string> GetListC
{
get
{
return this.mylist.AsEnumerable<String>();
}
}
}
You can use List(T).AsReadOnly():
return this.mylist.AsReadOnly()
which will return a ReadOnlyCollection.
Just use ReadOnlyCollection class, it is supported since .NET 2.0
Use the generic ReadOnlyCollection class (Collection.AsReadOnly()). It doesn't copy any objects which may have some strange results when the underlying collection is changed.
var foo = new List<int> { 3, 1, 2 };
var bar = foo.AsReadOnly();
foreach (var x in bar) Console.WriteLine(x);
foo.Sort();
foreach (var x in bar) Console.WriteLine(x);
But if you don't want a copy, that's the best solution.
I prefer returning IEnumerable, but you don't need to cast. Just do
public IEnumerable<string> StringList { get { return myList; }
List<string> is an IEnumerable<string>

Categories