method only adding to list if declared inside method - c#

For some strange reason my code throws an object reference error when I attempt to add to the list declared in my class. My _machineName property is visible. The XML exists and has data. I am sure this has something to do with how I instantiated Machines inside the method. Any suggestions? I'm drawing a blank.
public class Machines
{
public List<string>_machineName { get; set; } //list I would like to add to
public Machines()
{}
public List<Machines> GetMachineList()
{
XmlDocument xml = new XmlDocument();
List<Machines> _machinesList = new List<Machines>();
List<string> str = new List<string>(); //List that works
string zdPath = GetZeroDeploymentPath();
zdPath = zdPath + #"\ZeroDeploymentService\XML\CatalogFile.xml";
using (XmlReader xmlReader = XmlReader.Create(zdPath))
{
xmlReader.MoveToContent();
while (xmlReader.Read())
{
if (xmlReader.IsStartElement())
{
switch (xmlReader.Name.ToLower())
{
case "machinename":
str.Add(xmlReader.ReadString().Trim()); //Works
_machineName.Add(xmlReader.ReadString().Trim()); //Fails
break;
}
}
}
}
return _machinesList;
}

It's because you never instantiate the list. In the constructor of your Machines class you need to add:
this._machineName = new List<string();
As an aside, a public property should not start with an underscore.

Your property
public List<string>_machineName { get; set; }
allows you to access _machineName, but you never actually create the List. If you add the following line to your constructor it will instantiate the List then you will be able to Add to it.
_machineName = new List<string>;
BTW, the name of a public property usually is a capital letter so I would change the name from _machineName to MachineName.

An ObjectReferenceException will be thrown when attempting to act on a reference of your _machineName list until it is instantiated, which happens inside of your GetMachineList() function.
You will have to move your instantiation of this object either outside of that method and into either a constructor or in the class body, or you will have to call that method before calling _machineName

Related

Why doesn't name exist in the current context of shorthand member initialisation?

I am using an object initializer for a st object:
public class Container
{
public Container () { ContainedItem = new Item; }
public Item ContainedItem { get; set; }
}
public class Item
{
public string Value { get; set; }
}
var MyContainer = new Container()
{
// I want to populate the the property Value of the property Item
// with the second line rather than the first
ContainedItem = new Item() { Value = FooString }, // This works
ContainedItem.Value = FooString // This assigns to the same member but does not work
};
The second initializer line gives the error:
The name 'ContainedItem' does not exist in the current context.
Invalid initializer member declarator.
and suggests declaring ContainedItem somewhere in local scope.
Now as the first line works it can be seen that ContainedItem is in fact a valid property of Container and that MyContainer.ContainedItem is definitely not null... so why does the following line fail to recognise it?
The syntax for inline object initialisation is well specified. You can't just make stuff up and expect the compiler to understand. The syntax is strictly:
{
Property1 = Value1,
Property2 = Value2,
...
}
c.x is not a property of st. c is. Hence, you cannot say c.x = Bar[i].x
From the C# Language Specification section 7.6.10.2:
object-initializer:
{ member-initializer-listopt }
{ member-initializer-list , }
member-initializer-list:
member-initializer
member-initializer-list , member-initializer
member-initializer:
identifier = initializer-value
initializer-value:
expression
object-or-collection-initializer
You can assign values to "sub-properties" as it were, just not with that syntax. Here's a complete example:
using System;
public class Container
{
public Item Item { get; set; } = new Item();
}
public class Item
{
public string Value { get; set; }
}
class Test
{
static void Main(string[] args)
{
var container = new Container
{
Item = { Value = "hello" }
};
}
}
The object initializer in Main is equivalent to:
var tmp = new Container();
tmp.Item.Value = "hello";
var container = tmp;
Note that this relies on Container.Item returning a valid object without it having been explicitly initialized in the object initializer - which is the case in my example, but isn't always the case.
You can´t use an expression like c.x on the left side of an assignement within an initializer. This includes methods-calls as well as getters/setters:
var s = new S { x.MyMethod() };
The only thing you can do in an intializer is to set a property of the current type.
From MSDN:
Object initializers let you assign values to any accessible fields or
properties of an object
However c.x is not a field or property of st, it´s not even a valid name.
That´ll work however:
var s = new st();
{
c = new ct()
};
s.c.x = Bar[i].x;
That's cause you are trying to do inside object initializer which is for initializing the object members and c.x isn't a defined member of object s. Thus the said error. Rather try doing it outside of object initializer saying
s.c.x = Bar[i].x;

How to add a class property to a list of instances

I'm newbie in C#. Perhaps this is too simply to resolve but I'm really away of the solution.
I have this class:
public class TestSetups : TabelaCtset
{
public IList<TabelaCtsca> ValSetup { get { return m_valsetup; } }
private static List<TabelaCtsca> m_valsetup;
/// Constructor
public TestSetups(IDefinitionList dlist)
: base(dlist)
{
m_valsetup = new List<TabelaCtsca>();
}
}
I have another class called TestCase
public class TestCase : TabelaCttes
{
public IList<TestSetups> Setups { get { return m_setups; } }
private List<TestSetups> m_setups;
...
testcase.m_setups = new List<TestSetups>();
defs = gdl.GetDefinitions(testcase);
while (defs.MoveNext())
{
TestSetups testsetup = new TestSetups(defs);
IDefinitionList valsetup = gdl.GetDefinitions(testsetup);
{
TabelaCtsca ctsca = new TabelaCtsca(valsetup);
testsetup.ValSetup.Add(ctsca);
}
testcase.Setups.Add(testsetup);
}
return testcase;
...
}
I want to put all ctsca values in a ValSetup list. All works fine, except this line testcase.Setups.Add(testsetup);: I have the the properties of TestSetups class but my ValSetup property is always empty, when my while goes to another iteration.
Sorry for this weird explanation. I'm able to explain in more detail.
Update: In this situation, I store in each TestSetup just the last ValSetup value and not all the ValSetup of each TestSetup.
You've made m_valsetup a static property, but you're re-initializing every time you create a new instance of TestSetups. If you want it to be a shared list across all instances of TestSetups, then you could use a property initializer like this:
private static List<TabelaCtsca> m_valsetup = new List<TabelaCtsca>();
And remove the initialization of it in the constructor.
If you didn't intend for the list to be shared, then just remove the static keyword from its definition.

asp.net null reference error assigning values to object when values are present

I have a search page which is using strongly typed objects, but I have the values broken into specific groups.
Code behind page calls the following when the user clicks the search button (none of these fields are empty):
SearchCriteria sc = new SearchCriteria();
sc.Generic.id = txtId.Text;
sc.Generic.maxReturned = rblMaxReturned.SelectedIndex;
sc.DisplayOnly.category = txtCategory.Text;
sc.DisplayOnly.type = txtType.Text;
sc.Building.address = txtAddress.Text;
sc.Building.city = txtCity.Text;
The DataType file is defined like this:
[Serializable]
public class SearchCriteria
{
public _Generic Generic { get;set; }
[Serializable]
public class _Generic
{
public int id {get;set;}
public int maxReturned {get;set;}
}
public _DisplayOnly DisplayOnly { get;set; }
[Serializable]
public class _DisplayOnly
{
public int category {get;set;}
public int type {get;set;}
}
public _Building Building { get;set; }
[Serializable]
public class _Building
{
public int address {get;set;}
public int city {get;set;}
}
}
When the code executes, I get a nullreferenceerror even though all the items in the various textboxes have a value. However, if I take out the public _Building Building { get;set; } and call the class directly it works and populates the values. What's the best solution here? Should I not use intermediary definition and call the class directly? If so, how can I call the different groups without making four different calls on the code behind page?
You need to initialize the internal class instances. Simply declaring the variables doesn't mean that you can access their properties without creating the instances. You could easily do that in the constructor of the SearchCriteria class
[Serializable]
public class SearchCriteria
{
public SearchCriteria()
{
// Without these initialization the internal variables are all null
// and so assigning any property of a null object causes the error
Generic = new _Generic();
DisplayOnly = new _DisplayOnly()
Building = new _Building();
}
.....
}
When you create a new instance of your SearchCriteria class, the properties are not initialized, and so they all have a value of null. So now look at the very first line where you try to use one of those properties:
sc.Generic.id = txtId.Text;
Here, txtID.Text is perfectly fine, but sc.Generic is null. When you try to look up the it's .id property for assignment, that's where the exception is thrown.
To fix this, you need to initialize each of those properties to have an instance of their type. Additionally, it's probably a good idea to use a private set, like so:
public _Generic Generic { get;private set; }
This will still allow to make all the same assignments that are currently written, because that only requires a get action to retrieve the type instance. The assignment/set operation is on the property of the property.

Unwanted rewrite data in List

I have problem with store data in list collection. If I add new data it rewrite old data, and in list is still only one item.
Here is main method, from this method I call method OpenChatScreen, It’s method of ChatScreenManager class where is root of problen.
private void OpenTabChatWindow(string nick)
{
try
{
new System.Threading.Tasks.Task(() =>
{
IDetailData oponent = new DetailData();
oponent = Service.DetailData(Account, nick);
Execute.OnUIThread((System.Action)(() =>
{
//here I call problem method OpenChatScreen method where is the problem,
//it use still the same reference on object opponent
if (ChatScreenManager.OpenChatScreen(true, Account, oponent, Account.DetailData.Info.Nick))
{
AddConversationHistory(nick);
}
}));
}
).Start();
}
catch (Exception exception)
{
MsgBox.ShowException(exception);
}
}
Code from ChatScreenManager class:
public IDictionary<string,object> ActiveChatScreens { get; set; }
or
public IList<string,> ActiveChatScreens { get; set; }
Problem is same if I use dictionary or list.
public bool OpenChatScreen(bool useTabChat, IAccount account, IDetailData oponent, string avatarNick)
{
if (!ActiveChatScreens.Contains(oponent.Info.Nick))
{
if(useTabChat)
{
//in this method - OpenTabChat is problem
OpenTabChat(account, oponent, avatarNick);
return true;
}
}
return false;
}
private void OpenTabChat(IAccount account, IDetailData oponent, string avatarNick)
{
if (!ChatShellViewModel.IsActive)
{
OpenChatShell();
}
ChatShellViewModel.OpenChatTab(account, oponent, avatarNick);
//here is the root of problem, it use same reference of object opponent
ActiveChatScreens.Add(oponent.Info.Nick);
}
So I pass from method OpenTabChatWindow object type of DetailData and store som string property in List in another class, but is use same reference on this object and rewrite data in list.
I try create new insatce of object:
IDetailData oponent = new DetailData();
oponent = Service.DetailData(Account, nick);
And pass this object to problem method, but it didn’t solve it.
Now if I understand your examples.
You add objects to ActiveChatScreens.
Could it be that you are reusing the same object in the call to OpenChatScreen in the first place.
Id so then opponent will change and any reference to it will also change before these methods is even called?
Remember objects are reference structures, even if you change the data in them, the reference is still the same.

How can i add column name in list generic?

class MyExcelSheets
{
public List MyColumnNames { get; set; }
}
how can i add Excel data's column name in "List MyColumnNames ". it returns to me Object reference not set to an instance of an object.
i want to use above class in:
myexcelSheet = new MyExcelSheets();
myexcelSheet.MyColumnNames = new MyExcelSheets().MyColumnNames;
foreach (DataColumn col in dTable.Columns)
myexcelSheet.MyColumnNames.Add(col.ColumnName.ToString());
How can i solve it? Error: NullReferenceException
Assuming that public List MyColumnNames { get; set; } is actually declared as public List<string> MyColumnNames { get; set; }
The row:
myexcelSheet.MyColumnNames = new MyExcelSheets().MyColumnNames;
Should be:
myexcelSheet.MyColumnNames = new List<string>;
Though it would normally be better to do this in a constructor or something.
The Code myexcelSheet.MyColumnNames = new MyExcelSheets().MyColumnNames; only obtains the reference to the property , but it doesnt instantiate that.
Adding the code
this. MyColumnNames = new List<string>;
in a static constructor will solve the issue , as this part of the code will be called by the run time and we dont have to worry about instantiating state transfer objects (as it is in this case)
E.g.,
static MyExcelSheets(){this. MyColumnNames = new List<string>; }
Thanks,
Vijay

Categories