String.ToString() method on null String Object - c#

I have the following code:
namespace Rextester
{
public class Program
{
public static void Main(string[] args)
{
//Your code goes here
var obj=(person)Activator.CreateInstance(typeof(person));
Console.WriteLine(obj);
}
}
public class person
{
public int id { get; set; }
public string name { get; set; }
public DateTime dob { get; set; }
public override string ToString()
{
return id.ToString() + " " + name + " " + dob.ToString();
}
}
}
which yields the following output:
0 1/1/0001 12:00:00 AM
However, if change the person.ToString() to the following:
public override string ToString()
{
return id.ToString() + " " + name.ToString() + " " + dob.ToString();
}
I get the following error:
System.NullReferenceException: Object reference not set to an instance of an object.
at Rextester.person.ToString()
Can someone shed some light on it.
Edited

I'm guessing your code samples aren't correct as it stands in your question and you're actually seeing this behavior:
return id.ToString() + " " + name + " " + dob.ToString();
works
return id.ToString() + " " + name.ToString() + " " + dob.ToString();
doesn't work
This is because adding a null value to a string is legal but calling a method on a null instance is not.
See this question:
Why is adding null to a string legal?

Related

Oracle.ManagedDataAccess performance in C#

I am using Oracle database as my backend. For my workflow, I am building a dynamic query based on what the user has selected. This dynamic query fetches from the 5 different tables. I am fetching and reading all the columns from all 5 tables so then I can use the same logic from elsewhere as well.
Oracle.ManagedDataAccess.dll is used for the database access.
Code:
public class ClassEx
{
public ClassA ClassA { get; set; }
public ClassB ClassB { get; set; }
public ClassC ClassC { get; set; }
public ClassD ClassD { get; set; }
public ClassE ClassE { get; set; }
public List<ClassEx> Select()
{
List<ClassEx> ex = new List<ClassEx>();
string sql = "Select " + (new ClaasA()).GetFullString("a") + ", "
+ (new ClaasB()).GetFullString("b") + ", "
+ (new ClaasC()).GetFullString("c") + ", "
+ (new ClaasD()).GetFullString("d") + ", "
+ (new ClaasE()).GetFullString("e") +
" From Sysadm.TableA a, Sysadm.TableB b, Sysadm.TableC c, Sysadm.TableD d, Sysadm.TableE e" +
" Where a.Col1 = b.Col2" +
" And a.Col5 = c.Col2" +
" And a.Col6 = d.Col2" +
" And a.Col10 = e.Col2";
GenericDataReader dr = new GenericDataReader(sql);
while(dr.Read())
{
ClassEx dummy = new ClassEx();
dummy.ClassA = new ClassA(dr);
dummy.ClassB = new ClassB(dr);
dummy.ClassC = new ClassC(dr);
dummy.ClassD = new ClassD(dr);
dummy.ClassE = new ClassE(dr);
ex.Add(dummy);
}
return ex;
}
}
public ClassA
{
public int Col1 {get;set;}
...
public DateTime? Col30 {get;set;}
public ClassA(GenericDataReader dr)
{
Col1 = dr.GetInt("A_Col1")
Col2 = dr.GetString("A_Col2")
....
Col30 = dr.GetDateTime("A_Col30")
}
public string GetFullString(string alias)
{
if (!String.IsNullOrEmpty(alias))
alias = alias + ".";
return alias + "A_Col1, " +
alias + "A_Col2, " +
...
alias + "A_Col30"
}
}
public ClassB
{
public int Col1 {get;set;}
...
public DateTime? Col30 {get;set;}
public ClassB(GenericDataReader dr)
{
Col1 = dr.GetInt("B_Col1")
Col2 = dr.GetString("B_Col2")
....
Col30 = dr.GetDateTime("B_Col30")
}
public string GetFullString(string alias)
{
if (!String.IsNullOrEmpty(alias))
alias = alias + ".";
return alias + "B_Col1, " +
alias + "B_Col2, " +
...
alias + "B_Col30"
}
}
public ClassC
{
public int Col1 {get;set;}
...
public DateTime? Col25 {get;set;}
public ClassC(GenericDataReader dr)
{
Col1 = dr.GetInt("C_Col1")
Col2 = dr.GetString("C_Col2")
....
Col25 = dr.GetDateTime("C_Col25")
}
public string GetFullString(string alias)
{
if (!String.IsNullOrEmpty(alias))
alias = alias + ".";
return alias + "C_Col1, " +
alias + "C_Col2, " +
...
alias + "C_Col25"
}
}
public ClassD
{
public int Col1 {get;set;}
...
public DateTime? Col10 {get;set;}
public ClassD(GenericDataReader dr)
{
Col1 = dr.GetInt("D_Col1")
Col2 = dr.GetString("D_Col2")
....
Col10 = dr.GetDateTime("D_Col10")
}
public string GetFullString(string alias)
{
if (!String.IsNullOrEmpty(alias))
alias = alias + ".";
return alias + "D_Col1, " +
alias + "D_Col2, " +
...
alias + "D_Col10"
}
}
public ClassE
{
public int Col1 {get;set;}
...
public DateTime? Col35 {get;set;}
public ClassE(GenericDataReader dr)
{
Col1 = dr.GetInt("E_Col1")
Col2 = dr.GetString("E_Col2")
....
Col35 = dr.GetDateTime("E_Col35")
}
public string GetFullString(string alias)
{
if (!String.IsNullOrEmpty(alias))
alias = alias + ".";
return alias + "E_Col1, " +
alias + "E_Col2, " +
...
alias + "E_Col35"
}
}
Everything work well. Query execution does not take even a second to execute. However, while loop takes 40 seconds to read 750 records.
Which is unacceptable. Can you please help me in improving the while loop.
I am not sure how best it can read all the record in fastest way.
Thank you so much friends for your response.
I have found a bug in my data reader itself when commented out one after another to see the issue. I have found that in one case, it always going in the exception and so it slows down my data reader.
After solving the exception, now I do receive my result in 2 seconds.
Solved!
Thank you once again :)

How can I build a string from a list of strings in my viewmodel?

I have these properties in my viewmodel:
public string FullInfo => LastName + ", " + FirstName
+ " (" + string.Join(",",EmployeeRoles) + ")";
public List<EmployeeRoleViewModel> EmployeeRoles { get; set; }
... which produces this output:
Doe, John ({Project name}.Models.EmployeeRoleViewModel, {Project name}.Models.EmployeeRoleViewModel)
The output I'm looking for is this:
Doe, John (Assisting Manager, Senior developer)
The last bit with the string.Join is not doing what I want. I want to add a comma separated list of Titles from EmployeeRoles, which looks like this:
public class EmployeeRoleViewModel
{
public int RoleId { get; set; }
public string Title { get; set; }
public bool Selected { get; set; }
}
How can this be acheived?
You should target the Title property from EmployeeRoles object
public string FullInfo => LastName + ", " + FirstName
+ " (" + string.Join(",",EmployeeRoles.Where(r => r.Selected).Select(r => r.Title ).ToArray()) + ")";
EmployeeRoles is a class which it's .ToString() is not what you want. you have to selected it's titles:
public string FullInfo => LastName + ", " + FirstName
+ " (" + string.Join(",",EmployeeRoles.Select(er => er.Title)) + ")";

NewtonSoft.JSON deserializing not working

I have the following JSON string:
{
[
{
"error": {
"typeofdevice": 678,
"valueconvert": "",
"message": "oops something went wrong"
}
}
]
}
What is the best way to deserialize this and get the the value for 'Message'?
I tried:
JToken token = JArray.Parse(args.Result);
string message = (string)token["description"];
But then it says
the Array is missing an index, and its not working.
Rookie question I know.. But I can't figure it out :S.
Grtz.
using System;
using System.Collections.Generic;
namespace ConsoleApplication2
{
using Newtonsoft.Json;
internal class Program
{
private static void Main(string[] args)
{
string jsonString =
"["
+ "{"
+ " \"error\": "
+ " {"
+ " \"typeofdevice\": 678,"
+ " \"valueconvert\": \"\","
+ " \"message\": \"oops something went wrong\""
+ " }"
+ "}"
+ "]";
List<Data> data = JsonConvert.DeserializeObject<List<Data>>(jsonString);
Console.WriteLine(data[0].Error.typeofdevice);
}
public class Data
{
public Error Error { get; set; }
}
public class Error
{
public string typeofdevice { get; set; }
public string valueconvert { get; set; }
public string message { get; set; }
}
}
}
The above console app works but I have changed your JSON string as others rightly pointed out that its not valid JSON.
In addition, if you want to check your JSON data if it is correct or not, you can send your data here:
http://jsoneditoronline.org/index.html

"The name 'modToSend' does not exist in the current context"

I have this simple piece of coding in my Homecontroller.cs, but I receive the error message on the last line, saying "The name 'modToSend' does not exist in the current context". How is that possible? Only in the last line is it not known????
public class HomeController : Controller, IDisposable
{
private MvcEShop2.WcfEshop2Service.Eshop2ServiceClient proxy = null;
private String GetDuration(DateTime startdatum, DateTime einddatum)
{
String maand1 = startdatum.Month.ToString("MMMM");
String maand2 = einddatum.Month.ToString("MMMM");
String duration = "";
if (maand1 == maand2)
{
duration = startdatum.Day.ToString()
+ " - " + einddatum.Day.ToString()
+ " " + maand1
+ " " + startdatum.Year.ToString();
}
else
{
duration = startdatum.Day.ToString()
+ startdatum.Month.ToString("MMMM")
+ " - " + einddatum.Day.ToString()
+ " " + einddatum.Month.ToString("MMMM")
+ " " + startdatum.Year.ToString();
}
return duration;
}
public HomeController()
{
proxy = new MvcEShop2.WcfEshop2Service.Eshop2ServiceClient();
}
struct EventStruct
{
public SEvent Event { get; set; }
public String Duration { get; set; }
};
public ActionResult Index()
{
List<SEvent> modFromWcf = proxy.GetAllEventsByPeriod(#System.DateTime.Now.Year, #System.DateTime.Now.Year + 1, "EN").ToList();
List<EventStruct> modTosend = new List<EventStruct>();
foreach (SEvent item in modFromWcf)
{
EventStruct ES;
ES.Event = item;
ES.Duration = GetDuration(item.StartDate ,item.EndDate);
modTosend.Add(ES);
};
return View("Index", modToSend);
}
}
If that's a direct copy & paste from your code, check the case of the 'S' in your parameter to the View being returned.

Getters and Setters, getting multiple fields

public class Teams : INotifyPropertyChanged
{
public string CombinedTeams
{
get
{
return Combined;
}
set
{
{
CombinedTeams += value;
NotifiyPropertyChanged("Combined");
}
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void NotifiyPropertyChanged(string p)
{
if (null != p)
{
PropertyChanged(this, new PropertyChangedEventArgs(p));
}
}
private string Combined
{
get
{
return " " + HomeTeam + " " + HomeScore + " - " + AwayScore + " " + AwayTeam;
}
set
{
{
Combined += value;
}
}
}
public string HomeTeam { get; set; }
public string AwayTeam { get; set; }
public string HomeScore { get; set; }
public string AwayScore { get; set; }
}
I got a problem, when trying combine my strings together and having one LONG string that contains all the values from when I parse my XML I only get the First set of values,
basically I get
Team1 Score1 : Score2 Team2
as opposed to
Team1 Score1 : Score2 Team2 Team3 Score3 : Score4 Team4 Team5 Score5 : Score6 Team6
I am binding my Control to CombinedTeams
could you guys help me out? I just want to store the previous string and then combine the new string with the old one, I cant see it being hard but this is confusing me and reading up on it makes me more confused...
Thanks,
John
Your code concatenates the new value to an empty string (last = "").
You probably want to concatenate to the previous value.
I'm not sure what you are expecting, last is always initialized to "", so the += is irrelevant.
Seems like the class called Teams is really a game?
And I don't think setting HomeTeam, AwayTeam, HomeScore, AwayScore over and over again (and then saving this internally somehow) is a good way to keep track of multiple games.
Why don't you look at using a collection of games?
Try something like this:
In a GamesLib library:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
namespace GamesLib
{
public class Game
{
public string HomeTeam { get; private set; }
public string AwayTeam { get; private set; }
public string HomeScore { get; private set; }
public string AwayScore { get; private set; }
public string Combined
{
get
{
return " " + HomeTeam + " " + HomeScore + " - " + AwayScore + " " + AwayTeam;
}
}
public Game(string HomeTeam, string AwayTeam, string HomeScore, string AwayScore)
{
this.HomeTeam = HomeTeam;
this.HomeScore = HomeScore;
this.AwayTeam = AwayTeam;
this.AwayScore = AwayScore;
}
}
public class Games : List<Game>, INotifyPropertyChanged
{
public string CombinedTeams
{
get
{
var str = "";
foreach (Game g in this)
{
str += g.Combined;
}
return str;
}
}
public new void Add(Game g)
{
base.Add(g);
if ( PropertyChanged != null ) {
PropertyChanged(this, new PropertyChangedEventArgs("CombinedTeams"));
}
}
public event PropertyChangedEventHandler PropertyChanged;
}
}
In a console program:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using GamesLib;
namespace TestHarness
{
class Program
{
static void Main(string[] args)
{
var gs = new GamesLib.Games();
gs.PropertyChanged += new System.ComponentModel.PropertyChangedEventHandler(gs_PropertyChanged);
var g = new Game("hometeam", "awayteam", "1", "0");
gs.Add(g);
g = new Game("lions", "bears", "1", "0");
gs.Add(g);
Console.WriteLine("Final result:" + gs.CombinedTeams);
}
static void gs_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
var gs = sender as Games;
Console.WriteLine("Changed: " + gs.CombinedTeams);
}
}
}
The reason you are getting the incorrect results is because you have one property referring to another property, and the second property always returns a specific value.
This block of code, when called from elsewhere, will return the results of some other variable called "Combined" which you have defined below...
public string CombinedTeams
{
get
{
return Combined;
}
...
}
private string Combined
{
get
{
return " " + HomeTeam + " " + HomeScore + " - " + AwayScore + " " + AwayTeam;
}
...
}
Everything else is academic because you're getter(s) essentially always return " " + HomeTeam + " " + HomeScore + " - " + AwayScore + " " + AwayTeam.
I suspect you will want to restructure your code to be something more like this
public class Teams : INotifyPropertyChanged
{
private string Combined; // Backing for CombinedTeams
public string CombinedTeams
{
get
{
return Combined;
}
set
{
// This only concatinates values; Combined will get longer each time.
Combined += value;
// ViewModels should always notify after the vale has changed
NotifyOfPropertyChange("CombinedTeams");
}
}
// Adds a new team, assuming HomeTeam, HomeScore, AwayScore, and AwayTeam have been initialized
public void AddTeam()
{
CombinedTeams = " " + HomeTeam + " " + HomeScore + " - " + AwayScore + " " + AwayTeam;
}
}
Certainly there are better ways to do that, but that should get you a start, I hope.
General rule (broken all the time by the code-ninjas, which is fine) is that a Property shouldn't do any calculations of it's own, it's really there to allow public access to private data in the class.
It might be worthwhile to run through a couple of articles on C# Properties. Here are some suggestions to get you started: http://msdn.microsoft.com/en-us/library/x9fsa0sw(v=vs.80).aspx and http://msdn.microsoft.com/en-us/library/aa288470(v=vs.71).aspx and of course, some Good Search Results

Categories