I was using the "this" keyword in my default constructor, below is the code in the class movie
namespace Movie_List
{ enum GenreType { Action, War, Drama, Thriller };
class Movie
{
//Data Members
private String _title;
private int _rating;
private GenreType _type;
//Properties
public GenreType GenType
{
get { return _type; }
set { _type = value; }
}
public String Title
{
get { return _title; }
set { _title = value; }
}
public int Rating
{
get { return _rating; }
set { _rating = value; }
}
public Movie()
: this("Jaws", GenreType.Action, 4) { }
public Movie(String title, GenreType type, int rating ) //working ctor
{
Title = title;
GenType = type;
Rating = rating;
}
public override string ToString()
{
return String.Format(" {0} Genre : {1}, Rating: {2:d} Stars. ", Title, GenType, Rating);
}
}
I wanted to read in from a text file so i used this code in the MainWindow.xaml.cs
private void btnLoad_Click(object sender, RoutedEventArgs e)
{
string lineIn = "";
string[] filmarray;
using (StreamReader file = new StreamReader("filmlist.txt"))
{
while ((lineIn = file.ReadLine()) != null)
{
filmarray = lineIn.Split(new char[] { ',' });
moviecollection.Add(new Movie()
{
Title = filmarray[0],
GenType = (GenreType)Enum.Parse(typeof(GenreType), filmarray[1]),
Rating = Convert.ToInt32(filmarray[2]),
});
lstFilms.ItemsSource = moviecollection;
}
}
}
I dont need this bit of code now
: this("Jaws", GenreType.Action, 4)
But when i deleted it, the genre action and rating 0 stars still prints.
Why is this Happening does anyone know?
When you have this initialization:
Movie movie = new Movie();
the empty constructor
public Movie() : this("Jaws", GenreType.Action, 4) { }
calls the overloaded constructor which have several parameters:
public Movie(String title, GenreType type, int rating) { ... }
When you delete this line: this("Jaws", GenreType.Action, 4) { }, what is happening now is that you are only calling the empty constructor which does nothing at all.
So when you call
int ratingValue = movie.Rating;
the default value of integer which is zero is returned because you did set anything on it.
UPDATE
a simple if (maybe, if I understand what you mean)
Assuming Rating should be greater than zero.
public override string ToString()
{
if (Rating == 0)
{
return String.Format("{0}", Title);
}
else
{
return String.Format(" {0} Genre : {1}, Rating: {2:d} Stars. ", Title, GenType, Rating);
}
}
It's because enum and int are always initialized with default value of 0.
It's not like string - if you don't initialize it will equal null. If you want to emulate this behavior for int, you can always try using int? type.
To get more details on this subject take a look at Default Values Table (C#).
Related
Im trying to create a function to finds all books that have the given author and returns a list of books. The function will accept a first and last name as parameters.
I have the function header that i must specifically use, and im unsure how to proceed further. Would appreciate some help
public class Publisher
{
#region Private Member Variables
private String name;
private List<Book> Books = new List<Book>();
#endregion
#region Properties
[DataMember(Name = "Name")]
public String Namee
{
get { return name; }
set { name = value; }
}
[DataMember(Name = "Books")]
public List<Book> Booking
{
get { return Books; }
set { Books = value; }
}
#endregion
#region Methods
public Publisher() //default constructor
{
name = "Default Publisher";
new Book();
}
Book FindBook(string title)
{
IEnumerable<Book> Query =
(from x in Booking
where x.Title == title
select x);
if (Query != null)
{
Console.WriteLine("The book is: " + Query);
}
else
{
return null;
}
}
List<Book> FindAllBooks(string first, string last)
{
List<Book> resultList = new List<Book>();
foreach (Book x in Booking)
{
var authors = x.Arthur;
foreach(Author c in authors)
{
if(c.First == first || c.Last == last)
{
resultList.Add(x);
}
}
}
return resultList;
}
public override string ToString()
{
foreach (Book item in Books)
{
Console.WriteLine(item);
}
return "Publisher Name: " + name + "\n";
}
#endregion
}
}
Here is the class Book
public class Book
{
#region Private Member Variables
private string title;
private List<Author> author = new List<Author>();
private double price;
#endregion
public Book()
{
title = "mystory";
/* author.First = "sam";
author.Last = "Marty";
author.Background = "default";*/
new Author();
price = 20;
}
#region Properties
[DataMember(Name = "title")]
public string Title
{
get { return title; }
set { title = value; }
}
//****************************************************
// Method: Price
//
// Purpose: get set for price
//****************************************************
[DataMember(Name = "price")]
public double Price
{
get { return price; }
set { price = value; }
}
//****************************************************
// Method: Arthur
//
// Purpose: get set for Author
//****************************************************
[DataMember(Name = "author")]
public List<Author> Arthur
{
get { return author; }
set { author = value; }
}
#endregion
#region Methods
//****************************************************
// Method: ToString()
//
// Purpose: Output class contents of Book.cs
//****************************************************
public override string ToString()
{
foreach (Author item in author)
{
Console.WriteLine(item);
}
return "Book Title = " + title + "\n" + "Book Author = " + "\n" + "Book Price =" + price + "\n" ;
}
#endregion
}
}
you can do this the straightforward way or the fancy way (LINQ). I suggest the straightforward way. Not going to write the code for you since this is clearly an assignment and you need to have a go.
create empty output list of books (result list)
for each Book in the list of books
get author list
for each author in author list
if author first = first and author last = last add book to result list
return result list
make sure you use case insensitive match on author last and first
My professor wants us to create a reusable class and console app that lists book objects. I got the first part of the assignment where I am supposed to print the books I created, but now I am stuck on the part where I have to modify the data and print again using the same method and then check out two books and print again. I have tried to look at example online and although some of them have helped, none have been able to get me to pass this roadblock.
class LibraryBook
{
private string _bookTitle;
private string _authorName;
private string _publisher;
private int _copyrightYear;
private string _callNumber;
public LibraryBook(string booktitle, string authorname, string publisher, int ccyear, string callnumber)
{
BookTitle = booktitle;
AuthorName = authorname;
Publisher = publisher;
CopyrightYear = ccyear;
CallNumber = callnumber;
}
public string BookTitle
{
get
{
return _bookTitle;
}
set
{
_bookTitle = value;
}
}
public string AuthorName
{
get
{
return _authorName;
}
set
{
_authorName = value;
}
}
public string Publisher
{
get
{
return _publisher;
}
set
{
_publisher = value;
}
}
public int CopyrightYear
{
get
{
return _copyrightYear;
}
set
{
const int CYEAR = 2019;
if (value > 0)
_copyrightYear = value;
else
_copyrightYear = CYEAR;
}
}
public string CallNumber
{
get
{
return _callNumber;
}
set
{
_callNumber = value;
}
}
public bool Avail;
public void CheckOut()
{
Avail = true;
}
public void ReturnToShelf()
{
Avail = false;
}
public bool IsCheckedOut()
{
return Avail;
}
public override string ToString()
{
return $"Book Title: {BookTitle}{Environment.NewLine}" +
$"Author Name: {AuthorName}{Environment.NewLine}" +
$"Publisher: {Publisher}{Environment.NewLine}" +
$"Copyright Year: {CopyrightYear}{Environment.NewLine}" +
$"Call Number: {CallNumber}{Environment.NewLine}" +
$"Checked Out: {IsCheckedOut()}{Environment.NewLine}";
}
}
}
class Program
{
static void Main(string[] args)
{
LibraryBook[] favBooksArray = new LibraryBook[5];
favBooksArray[0] = new LibraryBook("Harry Potter and the Philospher's Stone", "J.K. Rowling", "Scholastic Corporation", 1997, "HA-12.36");
favBooksArray[1] = new LibraryBook("Harry Potter and the Chamber of Secret", "J.K. Rowling", "Scholastic Corporation", 2001, "HA-13.48");
favBooksArray[2] = new LibraryBook("Tangerine", "Edward Bloor", "Harcourt", 1997, "TB-58.13");
favBooksArray[3] = new LibraryBook("Roll of Thunder, Hear My Cry", "Mildred D. Taylor", "Dial Press", 1976, "RT-15.22");
favBooksArray[4] = new LibraryBook("The Giver", "Lois Lowry", "Fake Publisher", -1, "Fk200-1");
WriteLine($"------LIBRARY BOOKS------{Environment.NewLine}");
BooksToConsole(favBooksArray);
WriteLine($"------CHANGES MADE----- {Environment.NewLine}");
ChangesToBooks(favBooksArray);
BooksToConsole(favBooksArray);
WriteLine($"------RETURNING BOOKS TO SHELF------{Environment.NewLine}");
ReturnBooksToConsole(favBooksArray);
BooksToConsole(favBooksArray);
}
public static void BooksToConsole(LibraryBook[] favBooksArray)
{
foreach (LibraryBook books in favBooksArray)
{
WriteLine($"{books}{Environment.NewLine}");
}
}
public static void ChangesToBooks(LibraryBook[] favBooksArray)
{
favBooksArray[1].AuthorName = "*****The Rock*****";
favBooksArray[3].BookTitle = "****Totally Not A Fake Name*****";
favBooksArray[1].CheckOut();
favBooksArray[4].CheckOut();
}
public static void ReturnBooksToConsole(LibraryBook[] favBooksArray)
{
favBooksArray[1].ReturnToShelf();
favBooksArray[4].ReturnToShelf();
}
}
}
i am trying to make a project for my school. I am trying to read a table where some null values are in an integer column. I've made it an integer but i can't get the null values into the integer.
I've already searched in stackoverflow but none of the answers i could make at my project. Can someone provide me some help, tell me where i have to put the code to make it work again. I just started as programmer.
This is my database conn string + reader:
public static List<Klant> GetAlleklanten()
{
var result = new List<Klant>();
using (var conn = new SqlConnection(ConnectionString))
{
conn.Open();
const string query = "select k.klantid, k.naam, k.adres, k.telefoonnummer, k.woonplaats, k.email, k.wachtwoord, kp.klantpasid from klant k left join klantpas kp on k.klantid = kp.klantid";
SqlCommand selectKamers = new SqlCommand(query, conn);
SqlDataReader reader = selectKamers.ExecuteReader();
while (reader.Read())
{
Klant klant = new Klant((int)reader["klantid"], (string)reader["naam"], (string)reader["adres"], (string)reader["telefoonnummer"], (string)reader["woonplaats"], (string)reader["email"], (string)reader["wachtwoord"], (int)reader["klantpasid"]);
result.Add(klant);
}
reader.Close();
}
return result;
}
klantpasid is the one that also can return a null value instead of an integer.
Here is the class where the klantpasid is in the construtor:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FontysHotel
{
public class Klant
{
// instantie variabelen
private int klantid;
private string naam;
private string adres;
private string telefoonnummer;
private string woonplaats;
private string email;
private string wachtwoord;
private int? klantpasid;
// properties
public int Klantid
{
get
{
return klantid;
}
set
{
klantid = value;
}
}
public string Naam
{
get
{
return naam;
}
set
{
naam = value;
}
}
public string Adres
{
get
{
return adres;
}
set
{
adres = value;
}
}
public string Telefoonnummer
{
get
{
return telefoonnummer;
}
set
{
telefoonnummer = value;
}
}
public string Woonplaats
{
get
{
return woonplaats;
}
set
{
woonplaats = value;
}
}
public string Email
{
get
{
return email;
}
set
{
email = value;
}
}
public string Wachtwoord
{
get
{
return wachtwoord;
}
set
{
wachtwoord = value;
}
}
public int? Klantpasid
{
get
{
return klantpasid;
}
set
{
klantpasid = value;
}
}
// Constructor
public Klant(int klantid, string naam, string adres, string telefoonnummer, string woonplaats, string email, string wachtwoord, int klantpasid)
{
Klantid = klantid;
Naam = naam;
Adres = adres;
Telefoonnummer = telefoonnummer;
Woonplaats = woonplaats;
Email = email;
Wachtwoord = wachtwoord;
Klantpasid = klantpasid;
}
}
}
Please provide me some help, tell me where i have to place the right code so i can continue my school project. The error i am getting now is ''' The specified conversion is invalid
'''
You can check klantid for DBNull.Value, and if it is, assign corresponding special int value; so instead of
(int)reader["klantid"]
put
reader.IsDBNull(reader.GetOrdinal("klantid")) ? -1 : Conver.ToInt32(reader["klantid"])
a better way is to declare private int klantid; as private int? klantid; (nullable int):
private int? klantid; // it can accept null now
public int? Klantid
{
get
{
return klantid;
}
set
{
klantid = value;
}
}
then while reading from reader we can use turnary operator:
KlantId = !reader.IsDBNull(reader.GetOrdinal("klantid"))
? Conver.ToInt32(reader["klantid"])
: null;
I know a fix for you,
You change Klantpasid from int? to int
If klantpasid is null in your database, we set the value to 0 instead of null
public int Klantpasid
{
get
{
return klantpasid;
}
set
{
if( value == null){
klantpasid = 0;
}else {
klantpasid = value;
}
}
}
You can declare your property as nullable
public int? Klantid
{
get
{
return klantid;
}
set
{
klantid = value;
}
}
Check out more on documentation.
When you read your data with a DataReader, it will return DBNull.Value. Whe you want to fill your Klant.Klantpasid value (which is of type Nullable<int>), you will have to convert the value to Nullable<int> yourself. When ADO.NET was first implemented, there were no nullable values, so they introduced DBNull instead. More modern approaches like Entity Framework use nullable types instead.
You can write a helper method to help converting your read value to a nullable type:
static T? AsNullable<T>(object value) where T : struct {
switch (value) {
case T converted:
return converted;
case DBNull:
return default(T?);
default:
throw new InvalidCastException();
}
}
So instead of...
(int)reader["klantpasid"]
...you write:
AsNullable<int>(reader["klantpasid"])
And of course you change the type of your constructor parameter from int to int?.
This question already has answers here:
What is a NullReferenceException, and how do I fix it?
(27 answers)
Closed 7 years ago.
I am having problem with nullpointer. I cant seem to understand why my code is wrong. Any help will be greatly appreciated. This is my code:
protected void Page_Load(object sender, EventArgs e)
{
Product aProd = new Product();
// Get Product ID from querystring
string prodID = Request.QueryString["ProdID"].ToString(); (null pointer occurs at this line. )
prod = aProd.getProduct(prodID);
//Display product details on web form
lbl_ProdName.Text = prod.Product_Name;
lbl_ProdDesc.Text = prod.Product_Desc;
lbl_Price.Text = prod.Unit_Price.ToString("c");
img_Product.ImageUrl = "~\\Images\\" + prod.Product_Image;
//Store the value in invisible fields
lbl_Price.Text = prod.Unit_Price.ToString();
lbl_ProdID.Text = prodID.ToString();
}
These are the code for Product.cs. I still have no idea where my codes went wrong
public class Product
{
string _connStr = ConfigurationManager.ConnectionStrings["HealthDBContext"].ConnectionString;
private string _prodID = null;
private string _prodName = string.Empty;
private string _prodDesc = ""; // this is another way to specify empty string
private decimal _unitPrice = 0;
private string _prodImage = "";
private int _stockLevel = 0;
// Default constructor
public Product()
{
}
// Constructor that take in all data required to build a Product object
public Product(string prodID, string prodName, string prodDesc,
decimal unitPrice, string prodImage, int stockLevel)
{
_prodID = prodID;
_prodName = prodName;
_prodDesc = prodDesc;
_unitPrice = unitPrice;
_prodImage = prodImage;
_stockLevel = stockLevel;
}
// Constructor that take in all except product ID
public Product(string prodName, string prodDesc,
decimal unitPrice, string prodImage, int stockLevel)
: this(null, prodName, prodDesc, unitPrice, prodImage, stockLevel)
{
}
// Constructor that take in only Product ID. The other attributes will be set to 0 or empty.
public Product(string prodID)
: this(prodID, "", "", 0, "", 0)
{
}
// Get/Set the attributes of the Product object.
// Note the attribute name (e.g. Product_ID) is same as the actual database field name.
// This is for ease of referencing.
public string Product_ID
{
get { return _prodID; }
set { _prodID = value; }
}
public string Product_Name
{
get { return _prodName; }
set { _prodName = value; }
}
public string Product_Desc
{
get { return _prodDesc; }
set { _prodDesc = value; }
}
public decimal Unit_Price
{
get { return _unitPrice; }
set { _unitPrice = value; }
}
public string Product_Image
{
get { return _prodImage; }
set { _prodImage = value; }
}
public int Stock_Level
{
get { return _stockLevel; }
set { _stockLevel = value; }
}
Request.QueryString["ProdID"] is returning null.
So your ToString() call cause a System.NullPointerException
Solution : ensure that your Request.QueryString["ProdID"] call sends you back the correct object, or test the result yourself:
var obj = Request.QueryString["ProdID"];
string prodID = obj == null ? String.Empty : obj.ToString();
My problem is that I have a List<> variable connected to another class, and I want to get all the items from that List<> and put it into a string.
In the result string, i'd like to see callNum, copyNum, content, author, year, title
Here is where I'm trying to put it into a string
public class CItemControl
{
//declare a list variable
private List<CItem> mItems;
private CItem mNewItem;
//a method that instantiates the list
public CItemControl()
{
mItems = new List<CItem>();
}
//attribute to get all items
public List<CItem> Items
{
get { return mItems; }
}
public CItem NewItem
{
get { return mNewItem; }
}
//method to add item to the CItem list
public void AddItem(int callNum, int copyNum, string content, string author, string year)
{
mNewItem = new CItem(callNum, copyNum, content, author, year);
mItems.Add(mNewItem);
}
//method to return all items to a string
public CItem ListAllItems()
{
string allItems;
}
Here is the class where I'm trying to get the items from. There will be variables added later.
class CItem
{
//declare attributes
private string mTitle;
private string mAuthor;
private string mContent;
private string mYear;
private int mCopyNum;
private int mCallNum;
private bool mHold = false;
private bool mBorrowed = false;
private bool mShelf = false;
//overload a constructor
public CItem(int CallNum, int CopyNum, string Content, string Author, string Year)
{
callNum = CallNum;
copyNum = CopyNum;
content = Content;
author = Author;
year = Year;
}
//create the default constructor
public CItem()
{
callNum = 0;
copyNum = 0;
content = "";
author = "";
year = "";
}
//set attributes
public int callNum
{
get { return mCallNum; }
set { mCallNum = value; }
}
public string content
{
get { return mContent; }
set { mContent = value; }
}
public string author
{
get { return mAuthor; }
set { mAuthor = value; }
}
public string year
{
get { return mYear; }
set { mYear = value; }
}
public string title
{
get { return mTitle; }
set { mTitle = value; }
}
public int copyNum
{
get { return mCopyNum; }
set { mCopyNum = value; }
}
public bool hold
{
get { return mHold; }
}
public bool borrowed
{
get { return mBorrowed; }
}
public bool shelf
{
get { return mShelf; }
}
//display information for users
public string displayInfo()
{
return "Call Number: " + callNum + ". Copy Number: " + copyNum + ". Title: " + title +
". Author: " + author + ". Year Published: " + year + ". Content: " + content;
}
//new method to display status of item
public string displayStatus()
{
if (borrowed == true)
return "Item is currently being borrowed.";
if (shelf == true && hold == false)
return "Item is available for borrowing.";
else
return "Item is on hold";
}
Any help is much appreciated!
Thanks in advance.
ListAllItems shall look something like this
public string ListAllItems()
{
var sb = new StringBuilder(); // var is of type StringBuilder
mItems.ForEach(item => sb.Append(item.displayInfo());
return sb.ToString();
}
return String.Join("; ", allItems.Select(item => item.displayInfo()));
You don't provide a lot of informations on how and what informations you want in your result string.
Can't you achieve this objective with a simple loop ?
using System.Text;
(...)
public string ListAllItems()
{
StringBuilder allItems = new StringBuilder();
foreach(CItem itm in Items){
allItems.AppendLine(itm.displayInfo());
}
return allItems.ToString();
}
Stringbuilder is optional but is faster than string concatenation.
I don't normally like to add formatter methods to property bags like this. If you want the flexibility to change have many formatting implementations, you might want to make a seperate class do the formatting.
public interface IFormatter<in T>
{
string Format(T obj);
}
public class CItemFormatter : IFormatter<CItem>
{
public string Format(CItem item)
{
//formatting logic
}
}