public abstract class SingleValueObject<T> {
public T Value {get; protected set;}
public static bool operator == (SingleValueObject<T> o1, SingleValueObject<T> o2) {
if (((object)o1) == null || ((object)o2) == null) { return Object.Equals(o1, o2); }
return o1.Value.Equals(o2.Value);
public static bool operator != (SingleValueObject<T> o1, SingleValueObject<T> o2) {
if (((object)o1) == null || ((object)o2) == null) { return !Object.Equals(o1, o2); }
return !o1.Value.Equals(o2.Value);
public override bool Equals(Object o) {
if (o == null) { return false; }
return this.Value.Equals(((SingleValueObject<T>) o).Value);
public override int GetHashCode() {
return Value.GetHashCode();
public abstract class SingleIntegerValueObject : SingleValueObject<int> {
public override string ToString() { return String.Format("{0:#,0}", this.Value); }
public static implicit operator string(SingleIntegerValueObject v) => v.ToString();
public static implicit operator int(SingleIntegerValueObject v) => v.Value;
public abstract class SingleStringValueObject : SingleValueObject<string> {
public override string ToString() { return this.Value; }
public static implicit operator string(SingleStringValueObject v) => v.Value;
public class PlanName : SingleStringValueObject {
public PlanName(string value) {
public class PriceInYen : SingleIntegerValueObject {
public PriceInYen(int priceInYen) {
public static void PrintString(string s) {
public static void Main()
var planName = new PlanName("プラン名");
var priceInYen = new PriceInYen(10000);
var priceInYen2 = new PriceInYen(priceInYen * 2);
PrintString(priceInYen2);