I cannot create object that contains arrays of property inside object - c#

I am a new developer to c# MVC3.
I have a problem that I cannot create object that contains arrays of property inside object.
For example, I want to create instance ABC.Property[] for 10 arrays.
ABC.Property[0]
ABC.Property[1]
ABC.Property[2]
.....
....
ABC.Property[10]
I used debug mode to check and found out that ABC.Property[] is null. So i cannot add the value back to that object's array.
How to crate object with propeties's array?
thank you.
namespace finance3.Models
{
public class Expected_and_Risk
{
public decimal[] Prop { get; set; }
public decimal[] Forecast { get; set; }
public string[] Name { get; set; }
public decimal[] AxB { get; set; }
public decimal[] PowAxB { get; set; }
public decimal ExpectValue(Expected_and_Risk abc)
{
decimal count = abc.Forecast.Count();
Expected_and_Risk Result = new Expected_and_Risk();
for (int i = 0 ; i < count ; i++)
{
// here is the problem
// i cannot add new data to array because it has no dimemsion and i tried this
//
// Expected_and_Risk[] Result = new Expected_and_Risk[10];
//
// but it didn't work
Result.Name[i] = abc.Name[i];
Result.Prop[i] = abc.Prop[i];
Result.Forecast[i] = abc.Forecast[i];
Result.AxB[i] = abc.Prop[i] * abc.Forecast[i];
decimal a = Result.AxB[i];
decimal sumAxB =+ a;
double temp = (double)(a * a) ;
Result.PowAxB[i] = (decimal)(temp);
}
return Convert.ToDecimal(Result);
}
}
}

You need to add a Constructor in your class and in that constructor you can define the size for your property
public class Expected_and_Risk
{
//......//your code here
public Expected_and_Risk()
{
this.Prop = new decimal[10]; // this will define an array of 10 decimal elements for Prop
}
}
Also read about object oriented programming, Also check out this article An Intro to Constructors in C#

At the moment, you've got arrays within Expected_and_Risk, but you're never initializing the variables. You could do so within a constructor:
public Expected_and_Risk(int count)
{
Name = new string[count];
...
}
... but I'd suggest that's actually a nasty design. Any time you have lots of collections, all with the same count, where x[0] corresponds to y[0] and z[0] etc, you should consider having one collection of a custom type representing the encapsulation of those properties. For example:
// Must be an int, not a decimal - you can't create an array with a decimal count
int count = abc.Forecast.Count();
// Note: rename type to follow .NET naming conventions
Expected_and_Risk[] results = new Expected_and_Risk[count];
for (int i = 0; i < count; i++)
{
results[i].Name = abc[i].Name;
...
}
... except that of course now abc would be an array too. (It's not clear whether you're really just trying to copy all the values here, or whether you've got some business logic involved. There are better ways of copying values.)
Alternatively, if you really do want collections within Expected_and_Risk, you might want to consider using List<T> instead of arrays. That way you don't need to specify the count up-front.

Better way could be to add following method into Expected_and_Risk class and call it from within constructor.
EDIT - edit is done to make Initialize private, and call it within constructor.
void Initialize(int size)
{
Prop = new decimal[size];
AxB = new decimal[size];
Forecast = new decimal[size];
PowAxB = new decimal[size];
Name = new string[size];
}
public Expected_and_Risk(int size)
{
....
Initialize(size);
}
After that use it in ExpectValue like
Expected_and_Risk Result = new Expected_and_Risk(size)// size is 10 in example;

Related

Search in list of strings by name of the string

I have the following list I'm populating as I go through my class:
List<string> stringCollection = new List<string>();
I have a lot of static strings that I have declared before going to my class.
These strings are added to my list based on a collection of conditional expressions, meaning that it varies what kind of strings that I put into my list e.g.:
static string DescriptionText1 = "blabla",
DescriptionText2 = "blabla",
MagnitudeText1 = "blabla",
MagnitudeText2 = "blabla";
if(number < 2)
{
stringcollection.Add(DescriptionText1)
}
else
{
stringcollection.Add(DescriptionText2)
}
//Magnitude
if(magnitude > 128 && number < 256)
{
stringcollection.Add(MagnitudeText1)
}
else
{
stringcollection.Add(MagnitudeText2)
}
...
I then pass the list to my method in which I want to retrieve the strings like so:
public void Collection(List<string> ts)
{
string Description = ts.Find(DescriptionText); <--- my guess
string Magnitude = ts.Find(MagnitudeText);
}
How do I find the correct strings in my list, and write it to my newly declared strings in my method? - Even though they are appended hence 1,2,3 ... 6,7
Since you always put in Description first and then Magnitude, you can just do:
ts[0] // description
ts[1] // magnitude
Alternatively, consider writing a class that has the two properties:
// I don't know what these two things represent, please name it properly in your code!
class DescriptionMagnitude {
public string Description { get; }
public string Magnitude { get; }
public DescriptionMagnitude(string description, string magnitude) {
Description = description;
Magnitude = magnitude;
}
}
And then create an instance of this class and pass it around.
EDIT:
From your comment:
and then i would be able to search for my int variable?
It seems like you want to find the integer associated with the string. However, the 1 in DescriptionText1 is just part of an identifier. Why not just store the integer instead of the string?
Depending on what you are doing with the strings, an enum may be suitable:
enum Descriptions {
Foo = 0,
Bar = 1
Fizz = 2
}

C# new variable or reference?

public class Price
{
public string Symbol {get; set; }
public double AskPrice{get; set; }
public double BidPrice{get; set; }
public string Exchange{get; set; }
}
public class inputs
{
public IList<Price> Prices {get; set; }
}
var inputs = new
{
Prices = prices,
};
Price[] p = inputs.Prices.Where(x => x.Exchange == exchange).ToArray();
p.ForEach(x => x.AskPrice = 0);
For this code when I create new variable p, it is actually a reference to input.price, not a new variable. Why is this? Is there any best practice of how to deal with this behavior?
You did not make a change to p, p stayed the same, what you changed where the elements inside of p, the elements inside of p are shared between p and the original source.
To not get this behavior you need to "Deep copy" the objects when you make a new array, creating new objects for the elements with the same content as the original.
public class Price
{
public string Symbol {get; set; }
public double AskPrice{get; set; }
public double BidPrice{get; set; }
public string Exchange{get; set; }
public Price Clone()
{
var result = new Price();
result.Symbol = this.Symbol;
result.AskPrice = this.AskPrice;
result.BidPrice = this.BidPrice;
result.Exchange = this.Exchange;
return result;
}
}
public class inputs
{
public IList<Price> Prices {get; set; }
}
var inputs = new
{
Prices = prices,
};
Price[] p = inputs.Prices.Where(x => x.Exchange == exchange).Select(x=> x.Clone()).ToArray();
p.ForEach(x => x.AskPrice = 0);
Note, if you have any reference types inside of your class you need to recursively clone the entire data structure and will need to make copies of them too.
There are two different variables here - the first is the Price object(s), and the second is input.Prices, which is a List of prices.
Your LINQ code takes the inputs.Prices list, filters it and creates a new array from it, but all that does is create new collections. It doesn't change the actual objects that are in the collection. This is because classes, in C#, are all reference types, meaning that var price = input.Prices[0] just copies the reference to a single, specific instance in memory. You can copy those references between a dozen lists and arrays, but the objects are the same.
It seems that what you want is to clone or copy by value your Price objects. For that, you have two options:
Make Price a struct.
Structs, unlike classes, are value types and are copied-by-value, meaning a new copy is made whenever you assign it to a new variable. This, however, has a performance penalty, since the whole struct is copied every time it's assigned. Your struct takes up 24-32 bytes (two 64bit doubles and two 32/64 bit references to strings), which is more than the recommended rule of thumb of "no more than 16 bytes for structs", so it's probably a bad idea.
Make a Clone method.
Have your Price implement a Clone method which returns a copy of the object - or alternately, create a copy-constructor that creates a new Price with the old values. Use that in your LINQ:
public class Price
{
// your fields
public Price Clone()
{
return new Price
{
Symbol = this.Symbol,
BidPrice = this.BidPrice,
//etc.
}
}
}
var p = input.Prices.Where(x => x.Exchange == exchange).Select(x => x.Clone()).ToArray();

Need explanation on these bits of codes

i have recently stumbled upon a project(8-puzzle solver using A* alg) in which some codes are weird to me , because i have never seen the likes of it before .
what does this line mean ? what is this ?!
this[StateIndex]
whats this notation ? i cant undersand it at all !
i posted a sample of the class so that you can see it almost all together .
and one more question , is it not wrong to have a class implemented like StateNode? it used only a constructor to initialize its fields , and yet worst, declared them all public ! should he/she not have implemented Propertise for this task?
public enum Direction
{
Up = 1, Down = 2, Left = 3, Right = 4, UpUp = 5, DownDown = 6, LeftLeft = 7, RightRight = 8, Stop = 9
}
class StateNode
{
public int Parent;
public List<int> Childs;
public Direction Move;
public Direction ParentMove;
public byte[,] State;
public byte Depth;
public byte NullRow;
public byte NullCol;
public StateNode()
{ }
public StateNode(int NewParent, Direction NewMove, Direction ParentMove, byte NewDepth, byte NewNullRow, byte NewNullCol)
{
this.Parent = NewParent;
this.State = new byte[5, 5];
this.Move = NewMove;
this.ParentMove = ParentMove;
this.Depth = NewDepth;
this.NullRow = NewNullRow;
this.NullCol = NewNullCol;
this.Childs = new List<int>();
}
}
class StateTree : List<StateNode>
{
public static long MakedNodes;
public static long CheckedNodes;
public static byte MaxDepth;
public List<int> Successor1(int StateIndex)
{
List<int> RetNodes = new List<int>();
StateNode NewState = new StateNode();
//Up
if (this[StateIndex].NullRow + 1 <= 3 && this[StateIndex].ParentMove != Direction.Up)
{
NewState = ChangeItemState(this[StateIndex], StateIndex, Direction.Up, Direction.Down, Convert.ToByte(this[StateIndex].Depth + 1), this[StateIndex].NullRow, this[StateIndex].NullCol, Convert.ToByte(this[StateIndex].NullRow + 1), this[StateIndex].NullCol);
this.Add(NewState);
RetNodes.Add(this.Count - 1);
StateTree.MakedNodes++;
this[StateIndex].Childs.Add(this.Count - 1);
if (NewState.Depth > StateTree.MaxDepth)
StateTree.MaxDepth = NewState.Depth;
}
//Down
//Left
//Right
return RetNodes;
}
}
In your concrete case it's just access to the element, as it used inside the class that is derived from the List<T>
But it can be also indexer which enables index acces to your class object.
For example declare class like this:
public class ListWrapper
{
private List<int> list = ...
public int this[int index]
{
return list[index];
}
}
and after use it like
var lw = new ListWrapper();
//fill it with data
int a = lw[2]; //ACCESS WITH INDEX EVEN IF THE TYPE IS NOT COLLECTION BY ITSELF
this[StateIndex] is using the current class' indexer property. The indexer property is what allows you to access an element in a collection or list object as if it was an array. For instance:
List<string> strings = new List<string>();
strings.Add("Item 1");
strings.Add("Item 2");
strings.Add("Item 3");
string x = strings[0]; // Returns the first item in the list ("Item 1")
When you want to access the indexer property of your own class, however, you have to preface it with the this keyword. You'll notice that in your example, the StateTree class doesn't implement an indexer property, so that may be adding to your confusion. The reason it works is because StateTree inherits from List<StateNode> which does implement an indexer property.
But don't get confused between classes with indexer properties and arrays. Arrays are a completely different thing, though the syntax is similar. An array is a list of objects which can be accessed by an index. An indexer property is an unnamed property of a single object that acts as an array. So for instance, List<string> has an indexer property, so you can access the items it contains using the same syntax as an array index (as shown in the above example). However, you can still make an array of List<string> objects. So for instance:
List<string> strings1 = new List<string>();
strings1.Add("Item 1.1");
strings1.Add("Item 1.2");
List<string> strings2 = new List<string>();
strings2.Add("Item 2.1");
strings2.Add("Item 2.2");
List<string>[] stringsArray = new List<string>[] { strings1, strings2 };
object result;
result = stringsArray[0]; // Returns strings1
result = stringsArray[0][1]; // Returns "Item 1.2"
result = stringsArray[1][0]; // Returns "Item 2.1"
As far as StateNode goes, there's nothing technically wrong with it, and it's not unusual to have a constructor that initializes all the field values, but it's always better to use properties instead of public fields.
its Indexed Properties in C# .net .
you can check Tutorial : http://msdn.microsoft.com/en-us/library/aa288464(v=vs.71).aspx check here
this[StateIndex] is pointing to an element within the class. Because StateTree inherits from a List<T>, you have a collection that's accessible by index (in this case this[N] where N is the element's index.
this[StateIndex] is how you give a class and indexed property e.g
public class IndexedClass
{
private List<String> _content;
public IndexedClass()
{
_content = new List<String>();
}
public Add(String argValue)
{
_content.Add(argValue);
}
public string this[int index]
{
get
{
return _content[index];
}
set
{
_content[Index] = value;
}
}
}
so now you can do
IndexedClass myIndex = new IndexedClass();
myIndex.Add("Fred");
Console.Writeline(myIndex[0]);
myIndex[0] = "Bill";
Console.Writeline(myIndex[0]);
As for statenode if it's local to the class (a helper) then you could argue it as okay, I don't like it though, another ten minutes work it could be done properly. If it's public in the assembly, then it's not accpetable in my opinion. But that is an opinion.

NullReference Exception when assigning to a Class Integer[]

I want to be able to transfer values from one DataGridView in Form1 to another DataGridView in Form3. To do this I've chosen to filter them in 3 different variables which would be in classes so that i could access them later in Form3.
These are the classes: (I've had them as a single one with 3 variables already)
public class verify1
{
public static int[] CodUser { get; set; }
}
public class verify2
{
public static DateTime[] DataFim{ get; set; }
}
public class verify3
{
public static string[] Nome { get; set; }
}
Altho, when i am assigning values to the variables i get a NullReferenceException right in the first time the for runs.
This is the code i used to assign values:
int a = 0;
for (int i = 0; i < dataGridView1.RowCount - 1; i++)
{
DateTime date = Convert.ToDateTime(dataGridView1.Rows[i].Cells[2].Value);
if (date <= DateTime.Now)
{
verify1.CodUser[a] = Convert.ToInt32(dataGridView1.Rows[i].Cells[0].FormattedValue);
verify2.DataFim[a] = Convert.ToDateTime(dataGridView1.Rows[i].Cells[2].FormattedValue);
verify3.Nome[a] = Convert.ToString(dataGridView1.Rows[i].Cells[3].Value);
a++;
}
}
Now, what i don't understand is why Visual Studio says the value is null. The exception happens in the following line:
verify1.CodUser[a] = Convert.ToInt32(dataGridView1.Rows[i].Cells[0].FormattedValue);
(which is 17389) in the first place and won't let me go further. I cant see why it's returning null. By the way, the DataGridView is fully fulfilled with data.
Why is it returning null?
You have the public properties defined in your verify1 class, but you never initialize them. They're null.
You need to initialize the arrays before you use them:
int a = 0;
int rowCount = dataGridView1.RowCount;
verify1.CodUser = new int[rowCount];
verify2.DataFim = new DateTime[rowCount];
verify3.Nome = new string[rowCount];
You might also want to take another look at how to use classes properly. I'm guessing you don't need three separate classes each with a single static property. It looks like you should have a single VerifyInfo class with three fields. You can then store those in a List<T>:
public class VerifyInfo
{
public int CodUser { get; set; }
public DateTime DataFim { get; set; }
public string Nome { get; set; }
}
And then your loop code would be much cleaner:
var verifyInfos = new List<VerifyInfo>();
for(int i = 0; i < dataGridView1.RowCount - 1; i++)
{
var date = Convert.ToDateTime(
dataGridView1.Rows[i].Cells[2].Value);
if(date <= DateTime.Now)
{
verifyInfos.Add(new VerifyInfo
{
CodUser = Convert.ToInt32(dataGridView1.Rows[i].Cells[2].Value),
DataFim = Convert.ToDateTime(
dataGridView1.Rows[i].Cells[2].FormattedValue),
Nome = Convert.ToString(dataGridView1.Rows[i].Cells[3].Value)
});
}
}
The auto-properties are automatically intialized to default value of the returning type.
You are dealing with reference type Array. The defalt value for the reference type is null.
It's better, in this case, avoid to have auto properties, but use ordinary ones.
Example:
public class verify1
{
static List<int> codUser = new List<int>(); //definition
public static List<int> CodUser
{
get { return codUser;}
set {codUser = value;}
}
}
I esplicitly used a List<T> in this case, cause in moment of declaration you don't know the excat size of array, and alsoo, according to the code provided, it can vary.
EDIT
Can use it like this (in practice like you did before)
for (int i = 0; i < dataGridView1.RowCount - 1; i++)
{
DateTime date = Convert.ToDateTime(dataGridView1.Rows[i].Cells[2].Value);
if (date <= DateTime.Now)
{
verify1.CodUser[a].Add( Convert.ToInt32(dataGridView1.Rows[i].Cells[0].FormattedValue));
......
....
}
}
Hope this helps.
Isn't verify1.CodUser null? How do you create it?
EDIT:
I've editted my answer to reply to Bruno's comment. You have to initialize your arrays first to be able to use them. To make a simple test, please create a separate project, paste these two lines, run your project in debug mode and set the breakpoint after array2 is created:
Int32[] array1;
Int32[] array2 = new Int32[3];
What do you see in the first array? It is null because it wasn't initialized. All you have to do is to initialize your arrays as I did with array2.
Hope this helps,
Piotr
*sorry for formatting, stackoverflow javascript is somehow blocked for me.

Dynamically add values to List<double> using get & set

Is it possible to do somethink like
public class TestClass
{
public List<double> preTvoltage
{
get
{
return preTvoltage;
}
set
{
preTvoltage.Add(this); //how to add to the List??
}
}
}
The reason I want to do this (I do not know if this is a best method, just as far as my knowledge allows) because I have to get data from xml files that do not have always same number of data in them.
Later I want to fill a ListView rows and using list I can count how many items are and how many columns will be needed.
Here is a schematic of xml file:
and there are also Trigger and PostTrigger nodes in xml file with same data sorting.
and here is the listview I want to achive:
Link to full size image
So, there are some pin groups and each pingroup has lots of data, the above code I gave, was just to hold 1 of the voltage nodes in xml file.
I am pretty much listening for your ideas!
Thanks.
No, and it defies usage of properties - you should implement it as an Add (or similarly aptly named) method.
You can't add this, because this is a TestClass, not a double; and you can't add value, as otherwise suggested, because that is a List<double>, and Add requires a double.
It's not clear how you would use this, but it looks like a very bad idea to me. Setting a collection as a property is slightly unusual already, but it's even odder for that set operation to mutate the list. It's additionally weird that you're not using the value variable within the setter... why not?
You should consider what the calling code would look like, and whether that's really the clearest way of expressing the semantics you want.
set { preTvoltage.AddRange(value); }
As Jon Skeet is saying, this is not what you should do. Instead, do
TestClass t = new TestClass();
t.PreTvoltage.Add(...);
declaring the property as
public List<double> PreTvoltage
{
get { return preTvoltage; }
}
The type of a getter and setter must match.
You could have:
public List<double> preTvoltage
{
get
{
return preTvoltage;
}
set
{
preTvoltage.AddRange(value); //add all items in list assigned.
}
}
However, this seems like a bad idea as it would be confusing to users why the value got did not match the value just set. I would have the two operations as separate members, and the setter either not exist or else overwrite the existing preTvoltage entirely.
You can not implement it like this, the preferable way is to make collection controls like:
private IList<double> _preTvoltage = new List<double>();
public IEnumerable<double> preTvoltage
{
get
{
return preTvoltage.AsEnumerable();
}
}
public void AddTvoltage(double item)
{
_preTvoltage.Add(item);
}
Well I managed to solve my problem this way:
public class ITestData
{
public string pinName { get; set; } //Name of the pin
public double stressLevel { get; set; } //Stress level for latchup
public int psuCount { get; set;} //Number of PSU's
public List<double[]> preTrigger = new List<double[]>();
public List<double[]> inTrigger = new List<double[]>();
public List<double[]> postTrigger = new List<double[]>();
public void AddPreTrigger(double volt, double curr)
{
double[] data = new double[2];
data[0] = volt;
data[1] = curr;
preTrigger.Add(data);
}
public void AddInTrigger(double volt, double curr)
{
double[] data = new double[2];
data[0] = volt;
data[1] = curr;
inTrigger.Add(data);
}
public void AddPostTrigger(double volt, double curr)
{
double[] data = new double[2];
data[0] = volt;
data[1] = curr;
postTrigger.Add(data);
}
}

Categories