Duplicate - C#-NullReference Exception Error [duplicate] - c#

This question already has answers here:
What is a NullReferenceException, and how do I fix it?
(27 answers)
Closed 7 years ago.
I have built a simple code as shown below. While debugging, I am getting an error about "NullReference Handled Exception" at the code line:
X.DataPoints.Add(dp);
Here is the code snippet. Please advice on what am I missing?
public class RankPlot
{
public List<RankPlotDataPoint> DataPoints { get; set; }
}
public class RankPlotDataPoint
{
public double RankVal { get; set; }
public double ProbVal { get; set; }
}
ObservableCollection<RankPlot> EURresults = new ObservableCollection<RankPlot>();
public ObservableCollection<RankPlot> EURResults
{
get { return EURresults; }
set
{
EURresults = value;
base.OnPropertyChanged("StringList");
}
}
public void evaluate()
{
RankPlot X = new RankPlot();
for (double i = 0; i<5; i++)
{
RankPlotDataPoint dp = new RankPlotDataPoint();
dp.RankVal =i+1; // Y axis
dp.ProbVal = i; // X axis
X.DataPoints.Add(dp);
}
EURResults.Add(X);
}

You are getting Null Exception Because you need to initialize the List<RankPlotDataPoint> DataPoints. So Instead of Initialize DataPoints every time you create an instance of RankPlot, you should initialize like below:
Change your Below Statement:
public class RankPlot
{
public List<RankPlotDataPoint> DataPoints { get; set; }
}
To
public class RankPlot
{
public List<RankPlotDataPoint> DataPoints { get; set; } = new List<RankPlotDataPoint>();
}

in evaluate() method instead of
RankPlot X = new RankPlot();
write
RankPlot X = new RankPlot{DataPoints = new List<RankPlotDataPoint>()};
It'll initialize the list.

X.DataPoints = new List<RankPlotDataPoint>(); you never initialize the list before you add items to the list.

You are trying to add a value to a List<RankPlotData> that doesn't exist. With your property in the RankPlot class, you need to declare a new List of RankPlotData in your RankPlot class, and initialize it with .. new List<RankPlotData>(). Then, you should return that from your property get accessor.

Related

New class object error : Object reference not set to an instance of an object [duplicate]

This question already has answers here:
What is a NullReferenceException, and how do I fix it?
(27 answers)
Closed 3 years ago.
I encountered this error:
NullReferenceException: Object reference not set to an instance of an object
When creating the countStats object, it is NULL, after which I try to assign a value to the field of this class and get this error.
What am I doing wrong?
public async Task<MainPageViewModel> GetMainPageViewModelAsync()
{
var model = new MainPageViewModel();
var countStats = new StatsCountsViewModel(); // NULL
if (!_cache.TryGetValue("CountsStats", out countStats))
{
var result = await _contextRepository.GetStatsMainPageAsync();
countStats.CountSms = "300"; //ERROR
countStats.CountUsers = "600";
countStats.CountSuccessForecast = "1228";
model.Stats = countStats;
_cache.Set("CountsStats", countStats, new MemoryCacheEntryOptions
{
AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(10)
});
}
var forecasts = await _contextRepository.GetForecastsOnSaleAsync();
foreach (var item in forecasts)
{
model.Forecasts.Add(item);
model.Bookmaker.Add(await _contextRepository.GetBookmakersForForecastsAsync(item.Id));
}
return model;
}
public class StatsCountsViewModel
{
public string CountUsers { get; set; }
public string CountSms { get; set; }
public string CountSuccessForecast { get; set; }
}
This is your problem:
_cache.TryGetValue("CountsStats", out countStats)
out will change the object that countStats is pointing to. If it's found in the cache, then it will be the cached object. Great! If it isn't, then it will be null. You need to create a new instance in this case.
You should change your code to this:
var countStats = null;
if (!_cache.TryGetValue("CountsStats", out countStats))
{
countStats = new StatsCountsViewModel();
The problem is here:
if (!_cache.TryGetValue("CountsStats", out countStats))
You are passing the countStats using the out word, and somewhere in the try get value, you are setting a null in there.

How can I refer to a field of a class as some object, then use that object to obtain the field's value later?

Say I have the following code
public class FooClass
{
public int A { get; set; } = 0;
public int B { get; set; } = 0;
}
public class BarClass
{
public int X { get; set; } = 0;
public int Y { get; set; } = 0;
}
public class MyClass
{
int z = 0;
public FooClass Foo { get; set; } = new FooClass();
public BarClass Bar { get; set; } = new BarClass();
public static void MyMethod()
{
// List of MyClass objects
var myList = Enumerable.Range(1, 10).Select(_ => new MyClass()).ToList();
// Some flags set elsewhere
bool getFooAValues = true;
bool getBarYValues = true;
bool getClassZValues = true;
// Some statements that collects "field referecnes" of MyClass
var classFieldReferenceList = new List<...>();
if (getFooAValues)
classFieldReferenceList.Add(...);
if (getBarYValues)
classFieldReferenceList.Add(...);
if (getClassZValues)
classFieldReferenceList.Add(...);
// For each field reference
classFieldReferenceList.ForEach(classFieldRef =>
{
// For each class
myList.ForEach(myClassInst =>
{
// "Select"/"Apply" the reference to get the field value
var fieldValue = myClassInt.getTheFieldReferenceValue(classFieldRef);
// Do something with field value...
return fieldValue;
});
// Do something with the list of field values...
});
}
}
In this code, specifically in MyMethod, I create a list of MyClass objects. This class has a few fields, some are simply primitive types, some are instances of other classes. How can I refer to or address these fields in the form of some object I can pass around?
For example, I began writing code, akin to the following
public static void MyMethod()
{
// List of MyClass objects
var myList = Enumerable.Range(1, 10).Select(_ => new MyClass()).ToList();
// Some flags set elsewhere
bool getFooAValues = true;
bool getBarYValues = true;
bool getClassZValues = true;
if (getFooAValues)
{
var Avalues = myList.Select(myClassInst => myClassInst.Foo.A);
// Do Action X to list of values
}
if (getBarYValues)
{
var Yvalues = myList.Select(myClassInst => myClassInst.Bar.Y);
// Do Action X to list of values
}
if (getClassZValues)
{
var Zvalues = myList.Select(myClassInst => myClassInst.z);
// Do Action X to list of values
}
}
Where //Do Action X was quite a few lines of code that I would perform to each set of values (Plotting values on a plot, flags represent showing plot line or not). Though, I don't really want duplicate that code for each possible field I could refer/address within MyClass. Thus, I want to refer to a field by some "object" then "apply" that object to an instance of MyClass later to get the value of the field, if that makes sense.
I feel like this might be akin to defining a delegate? Though the delegate would be specific to some class structure?.. Or maybe there is some simple solution I have confused myself out of finding.
You can use Func<MyClass,object> delegate:
var classFieldReferenceList = new List<Func<MyClass,object>>();
if (...)
classFieldReferenceList.Add(m => m.Foo.A);
if (...)
classFieldReferenceList.Add(m => m.Foo.B);
if (...)
classFieldReferenceList.Add(m => m.Bar.X);
if (...)
classFieldReferenceList.Add(m => m.Bar.Y);
This is not ideal because object is used as the most common denominator, but that would be required for a "mixed bag" of types.
In your second example you could get away with a generic method:
private void DoActionsOnSelectedFields<T>(IEnumerable<MyClass> data, Func<MyClass,T> selector) {
foreach (T val in data.Select(selector)) {
... // Perform some common action
}
}

Object reference error in function in class [duplicate]

This question already has answers here:
CS0120: An object reference is required for the nonstatic field, method, or property 'foo'
(9 answers)
Closed 5 years ago.
I've defined a function in a class like this.
In this class, a value is either looked up or calculated if not found among a list of already calculate values.
If calculated anew, the result is stored in a list so that I can look it up in subsequent calls.
The problem is that the compiler doesn't like the way I do it and tells me
An object reference is required for the non-static field, method or property App.GetGoodFontSize(string, Size).
I don't understand what the compiler suggests. Which object reference does it mean?
Thank you.
public class App : Application
{
private List<udt> _list = new List<udt>();
private class udt
{
public int iLen { get; set; }
public Size nSize { get; set; }
public double FontSize { get; set; }
}
public double GetGoodFontSize(string uText, Xamarin.Forms.Size uTextRect)
{
for (int i = 0; i < _list.Count; i++)
{
if ((_list[i].iLen == uText.Length) && (_list[i].nSize == uTextRect))
{
return _list[i].FontSize;
}
}
int iBest = 100;
for (int i = 100; i > 6; i--)
{
Size nSize = GetTextSize(uText, i);
if (nSize.Width <= uTextRect.Width)
{
if (nSize.Height <= uTextRect.Height)
{
iBest = i;
break;
}
}
}
udt n = new udt();
n.iLen = uText.Length;
n.nSize = uTextRect;
n.FontSize = iBest;
_list.Add(n);
return iBest;
}
Change your code like this:
public static double GetGoodFontSize(string uText, Xamarin.Forms.Size uTextRect)
private static List<udt> _list = new List<udt>();

C# Adding a List<int> to a class [duplicate]

This question already has answers here:
What is a NullReferenceException, and how do I fix it?
(27 answers)
Closed 5 years ago.
I have a class that looks something like this:
public class Parent
{
private string sFirst_name1;
public string sParent1FirstName
{
get { return sFirst_name1; }
set { sFirst_name1 = value; }
}
private string sLast_name1;
public string sParent1LastName
{
get { return sLast_name1; }
set { sLast_name1 = value; }
}
private List<int> lChild_ID;
public List<int> lChildID
{
get { return lChild_ID; }
set { lChild_ID = value; }
}
public Parent(string sP1FN, string sP1LN, List<int> lCID)
{
lChild_ID= new List<int>();
sFirst_name1 = sP1FN;
sLast_name1 = sP1LN;
lChild_ID = lCID;
}
I create an instance of the class and add it to a List of type Parent with the line:
lParents.Add(new Parent(sParent1FNTemp, sParent1LNTemp,lParentChildIDTemp));
Where lParentChildIDTemp is just a null integer List.
Later on, I am trying to update the int list of the object at a specified index by saying:
lParents[iIndex].lChildID.Add(++iIDCounters);
And I get a null reference exception. I'm not too sure why, but I think it has something to do with my constructor for my class. The weird thing is, I have another class that does pretty much the same thing but it doesn't throw the exception. If anyone has any clues, I would be greatful.
Give your property is null, you should make sure you are not access null values to call methods or properties. If you do that, you will get an NullReferenceException. Try this:
var childIds = lParents[iIndex].lChildID;
if (childIds != null)
{
childIds.Add(++iIDCounters);
}
In your constructor, you could check the if the argument is null and define a default list int. If you for to set the argument, even if it is null, you will get null.
public Parent(string sP1FN, string sP1LN, List<int> lCID)
{
sFirst_name1 = sP1FN;
sLast_name1 = sP1LN;
if (lCID == null)
{
lChild_ID = new List<int>();
}
else
{
lChild_ID = lCID;
}
}
Since apparently you want to be able to pass in the lChildID during construction, change the constructor as so:
public Parent(string sP1FN, string sP1LN, List<int> lCID) {
sFirst_name1 = sP1FN;
sLast_name1 = sP1LN;
lChild_ID = lCID ?? new List<int>();
}
Drop the List of int argument in the ctor and why not use auto props:
public class Parent
{
public Parent(string sP1FN, string sP1LN)
{
LChildID = new List<int>();
sFirst_name1 = sP1FN;
sLast_name1 = sP1LN;
}
public List<int> LChildID { get; set; }
If you're not familiar with auto-implemented properties, see https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/auto-implemented-properties
Plus, you could also overload the ctor:
public Parent(string sP1FN, string sP1LN, List<int> lCID)
{
LChildID = lCID;
sFirst_name1 = sP1FN;
sLast_name1 = sP1LN;
}

how can i get an access to the elements of array in the class

I have a problem which I don't know how to solve. I have a class. This class has two arrays. I would like to get access via properties. How can I do it? I tried to use indexers, but it is possible if I have only one array. Here what I want to do:
public class pointCollection
{
string[] myX;
double[] myY;
int maxArray;
int i;
public pointCollection(int maxArray)
{
this.maxArray = maxArray;
this.myX = new string[maxArray];
this.myY = new double[maxArray];
}
public string X //It is just simple variable
{
set { this.myX[i] = value; }
get { return this.myX[i]; }
}
public double Y //it's too
{
set { this.myY[i] = value; }
get { return this.myY[i]; }
}
}
With this code, my X and Y are only simple variables, but not arrays.
If I use indexers, I get access only to one array:
public string this[int i]
{
set { this.myX[i] = value; }
get { return this.myX[i]; }
}
But how can I get access to second array?
Or I can't use property in this case? And I need only use:
public string[] myX;
public double[] myY;
An example with Tuples.
public class pointCollection
{
Tuple<String,Double>[] myPoints;
int maxArray;
int i;
public pointCollection(int maxArray)
{
this.maxArray = maxArray;
this.myPoints = new Tuple<String,Double>[maxArray];
}
public Tuple<String,Double> this[int i]
{
set { this.myPoints[i] = value; }
get { return this.myPoints[i]; }
}
}
And to access the points you do...
pointCollection pc = new pointCollection(10);
// add some data
String x = pc[4].Item1; // the first entry in a tuple is accessed via the Item1 property
Double y = pc[4].Item2; // the second entry in a tuple is accessed via the Item2 property
If I got it right, you need some kind or read/write-only wrapper for arrays to be exposed as properties.
public class ReadWriteOnlyArray<T>{
private T[] _array;
public ReadWriteOnlyArray(T[] array){
this._array = array;
}
public T this[int i]{
get { return _array[i]; }
set { _array[i] = value; }
}
}
public class pointCollection
{
string[] myX;
double[] myY;
int maxArray;
public ReadWriteOnlyArray<string> X {get; private set;}
public ReadWriteOnlyArray<double> Y {get; private set;}
public pointCollection(int maxArray)
{
this.maxArray = maxArray;
this.myX = new string[maxArray];
this.myY = new double[maxArray];
X = new ReadWriteOnlyArray<string>(myX);
Y = new ReadWriteOnlyArray<double>(myY);
}
}
and usage
var c = new pointCollection(100);
c.X[10] = "hello world";
c.Y[20] = c.Y[30] + c.Y[40];
The closest you'll come without either changing your data structure or moving to methods is to make a property that returns each array, much like you did in your first code block, except without the [i].
Then, you do var x = instanceOfPointCollection.MyX[someI]; for example.

Categories