Skip to content

Instantly share code, notes, and snippets.

@mrcampbell
Created May 22, 2017 04:39
Show Gist options
  • Save mrcampbell/cd1c0261cd21468a33274fe2d0e59a70 to your computer and use it in GitHub Desktop.
Save mrcampbell/cd1c0261cd21468a33274fe2d0e59a70 to your computer and use it in GitHub Desktop.
Demonstration of C# Object Inheritance
using System;
// The sealed keyword enables you to prevent the inheritance of a class or certain class members
// that were previously marked virtual.
public sealed class Book : Publication
{
/*
The first constructor uses the this keyword to call the other constructor.
This is a common pattern in defining constructors; constructors with fewer parameters
provide default values when calling the constructor with the greatest number of
parameters.
*/
public Book(string title, string author, string publisher) :
this(title, String.Empty, author, publisher)
{ }
public Book(string title, string isbn, string author, string publisher) :
base (title, publisher, PublicationType.Book)
{
// isbn argument must be a 10- or 13-character numeric string without "-" characters.
// We could also determine whether the ISBN is valid by comparing its checksum digit
// with a computed checksum.
//
if (! String.IsNullOrEmpty(isbn)) {
// Determine if ISBN length is correct:
if (! (isbn.Length == 10 | isbn.Length == 13))
throw new ArgumentException("The ISBN must be a 10- or 13-character numeric string");
ulong nISBN = 0;
if (! UInt64.TryParse(isbn, out nISBN))
throw new ArgumentException("The ISBN can consist of numeric characters only.");
}
// if passed all tests:
ISBN = isbn;
Author = author;
}
public string ISBN { get; }
public string Author { get; }
public Decimal Price { get; private set; }
// A three-digit ISO currency symbol.
public string Currency { get; private set; }
// Returns the old price, and sets a new price.
public Decimal SetPrice(Decimal price, string currency)
{
if (price < 0)
throw new ArgumentOutOfRangeException("The price cannot be negative");
Decimal oldValue = Price;
Price = price;
if (currency.Length != 3)
throw new ArgumentException("THe ISO currency symbol is a 3-character string.");
return oldValue;
}
/*
Unless it is overridden, the Equals(Object) method tests for reference equality.
That is, two object variables are considered to be equal if they refer to the same object.
In the case of the Book class, on the other hand, two Book objects should be equal if
they have the same ISBN.
*/
public override bool Equals(object obj)
{
Book book = obj as Book;
if (book == null)
return false;
else
return ISBN == book.ISBN;
}
/*
When you override the Equals(Object) method, you must also override the GetHashCode() method,
which returns a value that the runtime uses to store items in hashed collections for efficient
retrieval. The hash code should return a value that's consistent with the test for equality.
Since we've overridden Equals(Object) to return true if the ISBN properties of two Book objects
are equal, we return the hash code computed by calling the GetHashCode() method of the string
returned by the ISBN property.
*/
public override int GetHashCode() => ISBN.GetHashCode();
public override string ToString() => $"{(String.IsNullOrEmpty(Author) ? "" : Author + ", ")}{Title}";
}
using System;
using static System.Console;
namespace DotNetCML2
{
class Program
{
static void Main(string[] args)
{
var book = new Book("The Tempest", "0971655819", "Shakespeare, William",
"Public Domain Press");
ShowPublicationInfo(book);
book.Publish(new DateTime(2016, 8, 18));
ShowPublicationInfo(book);
var book2 = new Book("The Tempest", "Classic Works Press", "Shakespeare, William");
Write($"{book.Title} and {book2.Title} are the same publication: " +
$"{((Publication) book).Equals(book2)}");
Console.WriteLine("Press any key to exit...");
Console.ReadKey(true);
}
public static void ShowPublicationInfo(Publication pub)
{
string pubDate = pub.GetPublicationDate();
WriteLine($"{pub.Title}, " +
$"{(pubDate == "NYP" ? "Not Yet Published" : "published on " + pubDate):d} by {pub.Publisher}");
// The example displays the following output:
// The Tempest, Not Yet Published by Public Domain Press
// The Tempest, published on 8/18/2016 by Public Domain Press
// The Tempest and The Tempest are the same publication: False
}
}
}
using System;
public enum PublicationType { Misc, Book, Magazine, Article };
public abstract class Publication
{
private bool published = false;
private DateTime datePublished;
private int totalPages;
public Publication(string title, string publisher, PublicationType type)
{
if (publisher == null)
throw new ArgumentNullException("The publisher cannot be null.");
else if (String.IsNullOrWhiteSpace(publisher))
throw new ArgumentException("The publisher cannot consist only of whitespace.");
// publisher is considered valid at this point:
Publisher = publisher;
if (title == null)
throw new ArgumentNullException("The title cannot be null.");
else if (String.IsNullOrWhiteSpace(title))
throw new ArgumentException("The title cannot consist only of whitespace.");
Title = title;
// being an enum, Type is safe as an unchecked parameter
Type = type;
}
public string Publisher { get; }
public string Title { get; }
public PublicationType Type { get; }
public string CopyrightName { get; private set; }
public int CopyrightDate { get; private set; }
public int Pages
{
get { return totalPages; }
set
{
if (value <= 0)
throw new ArgumentOutOfRangeException("The number of pages cannot be zero or negative.");
totalPages = value;
}
}
public string GetPublicationDate()
{
if (!published)
return "NYP";
else
return datePublished.ToString("d");
}
public void Publish(DateTime datePublished)
{
published = true;
this.datePublished = datePublished;
}
public void Copyright(string copyrightName, int copyrightDate)
{
if (copyrightName == null)
throw new ArgumentNullException("The name of the copyright holder cannot be null.");
else if (String.IsNullOrWhiteSpace(copyrightName))
throw new ArgumentException("The name of the copyright holder cannot consist only of whitespaces.");
CopyrightName = copyrightName;
int currentYear = DateTime.Now.Year;
if (copyrightDate < currentYear - 10 || copyrightDate > currentYear + 2)
throw new ArgumentOutOfRangeException($"The copyright year must be between {currentYear - 10} and {currentYear + 1}.");
CopyrightDate = copyrightDate;
}
public override string ToString() => Title;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment