How can i add column name in list generic? - c#

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

Related

How to Insert only values of a class into another list class C#?

image that you defined a class as below;
public class Liste
{
public int valueInt { get; set; }
public List<string> valueString = new List<string>();
}
and I defined a varible which is also a list;
public List <Liste> oray2 = new List <Liste>();
public Liste oray3 = new Liste();
I would like to add value to a oray2 List manually,
oray3.valueInt = 10;
oray3.valueString.Add("Text1");
oray3.valueString.Add("Text2");
oray3.valueString.Add("Text3");
oray2.Add(oray3);
oray3.valueString.Remove("Text2");
This also effects oray2 List. So it seems
oray2.Add(oray3);
is not adding values to oray2 class but oray2[0] seems linked to oray3 class.
So What is the best and efficient way to add values of oray3 to oray2 without a link between oray3 and oray2[0] so resulting changing in oray3 will not affect oray2 list values?
My best solution;
oray3=null;
or
oray3=new Liste();
worked like a charm.
I see two choices: set oray3 to a new Liste object and set its properties rather than reuing the reference, or copy oray3 to a new Liste object and add that to the list.
It's not clear why you're reusing oray3 in the first place to kniw which of those is better.
Just make Liste a struct instead of a class i.e.
public struct Lex
{
public Lex()
{
}
public int valueInt { get; set; } = 0;
public List<string> valueString = new List<string>();
}
Classes in C# a reference type and so are passed by reference whereas structs are value types and so are passed by value.
Reference types pass around a reference to the declared variable so when they are assigned to another variable and changed, both variables are updated.
Value types simply copy their values when assigned so changes only occur on the variable that the changes were made to.
More info on value type and reference types here: https://www.tutorialsteacher.com/csharp/csharp-value-type-and-reference-type
I think this is what you want to do. This way a new oray3 object is created each time you call the GetOray3().
List<Liste> oray2 = new List<Liste>();
oray2.Add(GetOray3());
oray2.Add(GetOray3());
oray2.Add(GetOray3());
static Liste GetOray3()
{
Liste oray3 = new Liste();
oray3.valueInt = 10;
oray3.valueString.Add("Text1");
oray3.valueString.Add("Text2");
oray3.valueString.Add("Text3");
return oray3;
}
public class Liste
{
public int valueInt { get; set; }
public List<string> valueString = new List<string>();
}

Reflection to get and use class properties

I am trying to update a linked list from a datagridview using reflection so I don't have to write a line of code for each property.
The class:
public class clsUnderlying
{
public int UnderlyingID { get; set; }
public string Symbol { get; set; }
public double RiskFreeRate { get; set; }
public double DividendYield { get; set; }
public DateTime? Expiry { get; set; }
}
One line of code per property works:
UdlyNode.Symbol = (string)GenericTable.Rows[IDX].Cells["Symbol"].Value;
UdlyNode.Expiry = (DateTime)GenericTable.Rows[IDX].Cells["Expiry"].Value;
etc.
But there are many classes and class properties, so I'd prefer to use a loop and reflection, but I'm not sure how, and my attempt below has errors.
PropertyInfo[] classProps = typeof(GlobalVars.clsUnderlying).GetProperties();
foreach (var Prop in classProps)
{
Type T = GetType(Prop); // no overload for method GetType
UdlyNode.Prop.Name = Convert.T(GenericTable.Rows[IDX].Cells[Prop.Name].Value); // error on "Prop.Name" and "T.("
}
Thanks for any suggestions or links to further my understanding.
Reflection-based loop needs to use a different syntax:
Property type is a property of PropertyInfo,
Convert has a ChangeType method that takes System.Type, and
Property assignment needs to be done by calling SetValue
Therefore, your loop would look like this:
foreach (var p in classProps) {
p.SetValue(
UdlyNode
, Convert.ChangeType(
GenericTable.Rows[IDX].Cells[p.Name].Value
, p.PropertyType
)
);
}
I would suggest to use BindingSource. This way a changed value in the Grid will automatically be changed in your list:
BindingSource bs = new BindingSource();
bs.DataSource = yourList;
dataGridView1.DataSource = bs;
This would solve the case where you want to update values manually changed in the grid.

NullReferenceException on DataRow C# [duplicate]

This question already has answers here:
What is a NullReferenceException, and how do I fix it?
(27 answers)
Closed 7 years ago.
My problem is about an object not set to an instance after the first line inside the foreach loop. I really had a hard time thinking what should be instantiated here. So please guys, i just want to map the data from the DataTable to the a new List.
It errors out after this line,
aa.fieldParams[counter].field = row["ParameterField"].ToString();
Here is my actual code.
public class ParsedData
{
public static void ParseData(DataTable parsedData)
{
ObjectProperties aa = new ObjectProperties();
int counter = 0;
foreach (DataRow row in parsedData.Rows)
{
//parsedData.Rows = new DataTable[parsedData.Rows.Count];
aa.fieldParams[counter].field = row["ParameterField"].ToString();
aa.fieldParams[counter].parameterType = row["ParameterType"].ToString();
aa.fieldParams[counter].length = Convert.ToInt32(row["ParameterLength"]);
aa.fieldParams[counter].setIteration = Convert.ToInt32(row["NumberOfIterations"].ToString());
counter++;
}
}
}
Here is the ObjectProperties class.
public class ObjectProperties
{
public FieldParameters[] fieldParams { get; set; }
public int Counter { get; set; }
}
public class FieldParameters
{
public string field { get; set; }
public int length { get; set; }
public int setIteration { get; set; }
public string parameterType { get; set; }
}
aa.fieldParams[] do not have any values yet because the values of this will be coming from the parsedData.Rows. I am currently having the correct values on row but after the first line inside the loop it errors out.
parsedData values are coming from CSV file.
Initialize your array first:
ObjectProperties aa = new ObjectProperties();
aa.fieldParams = new FieldParameters[parsedData.Rows.Count]; //initialize your array first
You also haven't initialized your Array's elements:
foreach (DataRow row in parsedData.Rows)
{
aa.fieldParams[counter] = new YourArrayType(); //instantiate the current element
//...your code...
counter++;
}
Remember you have to instantiate every element of the array when your array contains reference type elements.
Check for null like this before using .ToString() on DataRow.
if (!(row["ParameterField"] is DBNull))
aa.fieldParams[counter].field = row["ParameterField"].ToString();
Also check for null values on other lines before casting.
You are using aa.fieldParams but I only see aa declared and initialized. What about fieldParams? Do you need to initialize it? Can you post the code for ObjectProperties class to see what does fieldParams hold?
May be aa.fieldParams is null[counter]?
Also if you do not trust the Column names in the DataRow then better check if the column with that name exists in the datatable before trying to access it.
Thanks,

method only adding to list if declared inside method

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

How to add data items to a List<Struct>

I have the following struct defined in a user control:
public struct ColumnData
{
public string ColumnName { get; set; }
public string ColumnDataItem { get; set; }
public bool ColumnIsHyperLink { get; set; }
public string ColumnHyperLinkURL { get; set; }
public string ColumnHyperLinkPK { get; set; }
}
I create a new instance of List<ColumnData> (In a different code behind that creates an instance of the user control) and want to pass in values to it, but how do I assign them to specific attributes within the struct object?
I create an instance of the struct using the following code:
List<ColumnData> DataItems = new List<ColumnData>();
This:
List<ColumnData> DataItems = new List<ColumnData>();
creates a new list.
This:
List<ColumnData> DataItems = new List<ColumnData>();
var cd = new ColumnData();
cd.ColumnName = "Taco";
DataItems.Add(cd);
creates a new list, a new struct, and adds an item to the list.
Change that to a class; all your woes relating to modifying struct properties (etc) will go away.
Alternatively, make it an immutable struct, and initialize it with the correct values at the point of creation - then the issue is moot, no matter how many times it is subsequently copied.
IMO the first is the right approach here.
so you need to do this:
public void AddToList(ColumnData columnData)
{
DataItems.Add(columnData);
}
and call this method from your other class passing an already created and initialized columnData object.
List<ColumnData> DataItems = new List<ColumnData>();
Is creating the list that holds your structs not your structs itself.
You could use structs here for performance reasons (faster then classes).
ColumnData data = new ColumnData
{
ColumnName = "Blaa"
};
DataItems.Add(data);

Categories