I'm noticing that I am unable to add to a list of objects past index 0. Any other index returns a null reference.
public class MultiValidation
{
public List<SingleValidation> validations { get; set; }
public MultiValidation(List<string> numArray)
{
for(int i = 0; i<numArray.Count; i++)
{
SingleValidation individual = new SingleValidation(Validate.idArray[i], Validate.actionArray[i], Validate.expiryArray[i]);
validations = new List<SingleValidation>();
validations.Add(individual);
Console.WriteLine(validations[i].action);
}
}
Here is the constructor used for SingleValidation
public SingleValidation(string ide, string ac, string exDate)
{
this.action = ac;
this.expiry = exDate;
this.id = ide;
}
I have tested that idArray[i],actionArray[i],expiryArray[i] are all strings.
validations = new List<SingleValidation>();
This should be outside the for loop.
{
validations = new List<SingleValidation>();
for(int i = 0; i<numArray.Count; i++)
{
SingleValidation individual = new SingleValidation(Validate.idArray[i],
Validate.actionArray[i], Validate.expiryArray[i]);
validations.Add(individual);
Console.WriteLine(validations[i].action);
}
}
Related
I want to check if a value in one list is in a second list. The second list is a 2 dimensional list defined in a class.
Here's some sample data.
tagNoMatchList[0] = "</Configuration>"
tagNoMatchList[1] = "<SWCheck>"
tagNoMatchList[2] = "</SWCheck>"
tagNoMatchList2[0].col = "A29"
tagNoMatchList2[0].tag = "</Configuration>"
tagNoMatchList2[1].col = "A52"
tagNoMatchList2[1].tag = "</SWCheck>"
public class tagNoMatchClass
{
public string tag { get; set; }
public string col { get; set; }
}
var tagNoMatchList = new List<string>();
var tagNoMatchList2 = new List<tagNoMatchClass>();
tagNoMatchList2.Add(new tagNoMatchClass
{
tag = formatTag,
col = Globals.ConvertColumnNumberToName(Globals.HeaderColumns[Globals.COLUMN_FORMATTING_TAG]) + rowIdx.ToString(),
});
bool test = tagNoMatchList[formatTagError].Any(x => tagNoMatchList2.Any(y=>x.Equals(y.tag)));
In the code above, test always has a value of false. It should be true when it tests tagNoMatchList[0] == tagNoMatchList2[0].tag and tagNoMatchList[2] == tagNoMatchList2[1].tag
I have tried various things and can't figure out what I'm doing wrong.
Thank you, jdweng. I must have my terminology wrong. I referred to tagNoMatchClass as a 2 dimensional List. It almost works, but not quite. The code below gives me exactly the opposite of what I want.
for (int formatTagError = 0; formatTagError < tagNoMatchList.Count; formatTagError++)
{
if (tagNoMatchList2.Any(x => x.tag == tagNoMatchList[formatTagError]))
{
// Do something
}
}
I tried the following, but the if always evaluates to true. There's something that I'm not understanding about the Any syntax.
for (int formatTagError = 0; formatTagError < tagNoMatchList.Count; formatTagError++)
{
if (tagNoMatchList2.Any(x => x.tag != tagNoMatchList[formatTagError]))
{
// Do something
}
}
Try something like this :
public class tagNoMatchClass
{
public string tag { get; set; }
public string col { get; set; }
}
public class Test
{
List<string> tagNoMatchList = new List<string>();
List<tagNoMatchClass> tagNoMatchList2;
public Test()
{
tagNoMatchList2 = new List<tagNoMatchClass>();
tagNoMatchList.Add("</Configuration>");
tagNoMatchList.Add("<SWCheck>");
tagNoMatchList.Add("</SWCheck>");
tagNoMatchList2.Add(new tagNoMatchClass() { col = "A29", tag = "</Configuration>"});
tagNoMatchList2.Add(new tagNoMatchClass() {col = "A52", tag = "</SWCheck>"});
bool test = tagNoMatchList2.Any(x => x.tag == tagNoMatchList[0]);
}
}
It works like this:
for (int formatTagError = 0; formatTagError < tagNoMatchList.Count; formatTagError++)
{
if (!tagNoMatchList2.Any(x => x.tag == tagNoMatchList[formatTagError]))
{
// Do something
}
}
Thanks very much for getting me close enough to where I could figure out the rest.
I have a parameterized constructor and a default constructor. They both create a new object array with x length, however, when I try to access the array in the Add method, it returns the value "null". I can't initialize the array in the fields because I don't know what size the user wants it to be, but I don't know how to access the 'updated' array later in the code. I get a NullReferenceException() on the line of code: if (count > data.Length) because data has the value null.
class CustomList
{
private int count;
private String[] data;
public int Count
{
get { return count; }
}
public CustomList(int arrayNum)
{
String[] data = new String[arrayNum];
}
public CustomList(): this(4)
{
}
public void Add (String item)
{
if (count > data.Length)
{
String[] temp = new String[count * 2];
for (int i = 0; i < data.Length; i++)
{
temp[i] = data[i];
}
data = temp;
}
data[count] = item;
count++;
}
Change this:
public CustomList(int arrayNum)
{
String[] data = new String[arrayNum];
}
To this:
public CustomList(int arrayNum)
{
data = new String[arrayNum];
}
You have accidentally created a local variable in the constructor which is being assigned to instead of the field that you wanted to assign to.
Change your code.
Your data object in constructor is local variable.
And you are not initializing your instance data object.
class CustomList
{
private int count;
private String[] data;
public int Count
{
get { return count; }
}
public CustomList(int arrayNum)
{
data = new String[arrayNum];
}
public CustomList(): this(4)
{
}
public void Add (String item)
{
if (count > data.Length)
{
String[] temp = new String[count * 2];
for (int i = 0; i < data.Length; i++)
{
temp[i] = data[i];
}
data = temp;
}
data[count] = item;
count++;
}
I have a base Message objects and then many more specific Message objects that inherit from the Message object. I want to be able to store some messages into a List of Lists. I need to be able to find the index of the outer List where there is a certain child message with a particular property value. (For my specific project, the order in which I add the messages to the List is always the same, so I will know which message is at which index.)
namespace Project
{
public class Message {} //base class
}
Here's two example child Messages:
class ABCMessage : Message
{
public ABCMessage() { }
public string ABCproperty1 { get; set; }
public string ABCProperty2 { get; set; }
public string ABCProperty3 { get; set; }
}
class XYZMessage : Message
{
public XYZMessage() { }
public string XYZproperty1 { get; set; }
public string XYZProperty2 { get; set; }
}
And here is what I want to do:
public static List<List<Message>> MessageList;
ABCMessage abcMessage = new ABCMessage();
abcMessage.ABCProperty1 = 1;
abcMessage.ABCProperty2 = 2;
abcMessage.ABCProperty3 = 3;
List<Message> myList = new List<Message>();
myList.Add(abcMessage);
//...
int index;
for (int i = 0; i < MessageList.Count; i++) {
if (MessageList[i][0].ABCProperty2 == 5) {
index = i;
break;
}
}
However, the problem is that I'm not able to call that property (or any property for that matter). Does anyone know how to solve this problem? Perhaps do I need to put properties in my Message class? (The only reason I wanted to do inheritance was to make it easier to make a List of Lists.)
The solution is to cast each message to ABCMessage and then, if not null, it's a instance of ABCMessage and so can have it's properties tested:
int index;
for (int i = 0; i < MessageList.Count; i++)
{
var message = MessageList[i][0] as ABCMessage;
if (message != null && message.ABCProperty2 == 5)
{
index = i;
break;
}
}
As not everyone likes the as/test for null approach, the other option is to use is:
for (int i = 0; i < MessageList.Count; i++)
{
var message = MessageList[i][0] as ABCMessage;
if (MessageList[i][0] is ABCMessage && (ABCMessage)(MessageList[i][0]).ABCProperty2 == 5)
{
index = i;
break;
}
}
However, as of C# 6, a new option (the null-conditional operator or "Elvis operator" as it's also known) exists, that uses the best of both worlds:
for (int i = 0; i < MessageList.Count; i++)
{
var message = MessageList[i][0] as ABCMessage;
if (message?.ABCProperty2 == 5)
{
index = i;
break;
}
}
The message?.ABCProperty2 == 5 syntax only tests ABCProperty2 if message is not null, removing the need for the != null test.
Here is the code snippet from my LinqPad:
public class Elephant{
public int Size;
public Elephant()
{
Size = 1;
}
}
public struct Ant{
public int Size;
}
private T[] Transform2AnotherType<T>(Elephant[] elephantList)
where T:new()
{
dynamic tArray = new T[elephantList.Length];
for (int i = 0; i < elephantList.Length; i++)
{
tArray[i] = new T();
tArray[i].Size = 100;
//tArray[i].Dump();
}
return tArray;
}
void Main()
{
var elephantList = new Elephant[2];
var elephant1 = new Elephant();
var elephant2 = new Elephant();
elephantList[0] = elephant1;
elephantList[1] = elephant2;
elephantList.Dump();
var r = Transform2AnotherType<Ant>(elephantList);
r.Dump();
}
I want to change one object array of known type,Elephant,to another object array of type T. T is not a class,but limited to struct which
provided by the already existed API.And every instance of type T shares some common property,says Size,but also has their own particular property which
I have omitted in my example code.So I put dynamic keyword inside the Transform2AnotherType<T>.
And I could not even to use Dump to make sure if the assignment has made effect,thus will throw RuntimeBinderException.
My question is: how to correctly make the assignment in such a struct array and return it back properly?
I suggest change your code like this:
public class Elephant
{
public Elephant()
{
Size = 1;
}
public int Size { get; set; }
}
public struct Ant
{
public int Size { get; set; }
}
private static T[] Transform2AnotherType<T>(Elephant[] elephantList)
where T : new()
{
T[] tArray = new T[elephantList.Length];
for (int i = 0; i < elephantList.Length; i++)
{
dynamic arrayElement = new T();
arrayElement.Size = 100;
tArray[i] = arrayElement;
//tArray[i].Dump();
}
return tArray;
}
static void Main()
{
var elephantList = new Elephant[2];
var elephant1 = new Elephant();
var elephant2 = new Elephant();
elephantList[0] = elephant1;
elephantList[1] = elephant2;
//elephantList.Dump();
var r = Transform2AnotherType<Ant>(elephantList);
//r.Dump();
}
I'm trying to populate a DataTreeListView from ObjectListView library using a list. Unfortunately I am unable to achieve it, there is nothing displayed even though there is a count of item inside the List itself.
Class.cs
public class Class
{
protected string xName;
protected int xId;
protected int xParentId;
protected int happinessStatus;
protected int salaryStatus;
public Class()
{
this.xName = "";
this.xId = 0;
this.xParentId = 0;
this.happinessStatus = 0;
this.salaryStatus = 0;
}
public String Name
{
get { return this.xName; }
set { this.xName = value; }
}
public int Id
{
get { return this.xId; }
set { this.xId = value; }
}
public int ParentId
{
get { return this.xParentId; }
set { this.xParentId = value; }
}
public int HappinessStatus
{
get {return this.happinessStatus; }
set { this.happinessStatus = value; }
}
public int SalaryStatus
{
get { return this.salaryStatus; }
set { this.salaryStatus = value; }
}
public static List<Class> GetList()
{
List<Class> oList = new List<Class>();
Class oClass = new Class();
oClass.Name = "Person A";
oClass.Id = 1;
oClass.ParentId = 0;
oClass.HappinessStatus = 1;
oClass.SalaryStatus = 1000;
oList.Add(oClass);
oClass.Name = "Person B";
oClass.Id = 2;
oClass.ParentId = 1;
oClass.HappinessStatus = 1;
oClass.SalaryStatus = 2000;
oList.Add(oClass);
oClass.Name = "Person C";
oClass.Id = 3;
oClass.ParentId = 1;
oClass.HappinessStatus = 1;
oClass.SalaryStatus = 1000;
oList.Add(oClass);
return oList;
}
On the MainForm's Load Event,
I did the following:
List<Class> list = new List<Class>();
list = Class.GetList();
dataTreeListView1.DataSource = list;
On the designer view, I've also created columns which has got aspect name set to each of the property of the class file except the Id and ParentId.
KeyAspectName : Id
ParentKeyAspectName: ParentId
I did a small messagebox to show the count of the item in the list, its correct but nothing displayed out on the dataTreeListView control.
May I know what is wrong with my coding?
Did you set KeyAspectName, ParentKeyAspectName and RootKeyValue accordingly?
If you did it using the designer, RootKeyValue may be your problem:
Due to the limitations of the Designer in the IDE, RootKeyValue can only be given a string value through the IDE. If your ParentKey is not of type string, you will have to set its value through code.
Since you parent key is of type int use
dataTreeListView1.RootKeyValue = 0;
Note that in contrast to the basic OLV, you don't need to add columns manually. If you want to hide the key columns set ShowKeyColumns = false.
EDIT:
There is another mistake in you code. You add the same instance of the object oClass 3 times. Use oClass = new Class(); before initializing a new person.