Skip to content

Instantly share code, notes, and snippets.

@jahmai-ca
Created August 21, 2015 06:46
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jahmai-ca/8e0fb0b18dd370de7fc0 to your computer and use it in GitHub Desktop.
Save jahmai-ca/8e0fb0b18dd370de7fc0 to your computer and use it in GitHub Desktop.
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
namespace Project
{
public class DomainEqualityComparer : IEqualityComparer
{
public static readonly DomainEqualityComparer Default = new DomainEqualityComparer();
public new bool Equals(object x, object y)
{
if (ReferenceEquals(x, y))
return true;
if (ReferenceEquals(x, null))
return false;
if (ReferenceEquals(null, y))
return false;
var xProperties = GetProperties(x.GetType()).Distinct(PropertyInfoComparer.Default).ToArray();
var yProperties = GetProperties(y.GetType()).Distinct(PropertyInfoComparer.Default).ToArray();
if (xProperties.Length != yProperties.Length)
return false;
if (xProperties.Intersect(yProperties, PropertyInfoComparer.Default).Count() != xProperties.Length)
return false;
foreach (var xProp in xProperties)
{
var yProp = yProperties.First(_ => _.Name == xProp.Name);
var xValue = xProp.GetValue(x);
var yValue = yProp.GetValue(y);
if (ReferenceEquals(xValue, yValue))
continue;
if (ReferenceEquals(xValue, null))
return false;
if (ReferenceEquals(null, yValue))
return false;
if (!xValue.Equals(yValue))
return false;
}
return true;
}
public int GetHashCode(object obj)
{
if (obj == null)
throw new ArgumentNullException("obj");
var t = obj.GetType();
var hashCode = 0;
foreach (var prop in GetProperties(t))
{
var value = prop.GetValue(obj);
hashCode = (hashCode*397) ^ (value == null ? 0 : value.GetHashCode());
}
return hashCode;
}
private static IEnumerable<PropertyInfo> GetProperties(Type t)
{
while (t != null && t != typeof (object) && t != typeof (ValueType))
{
foreach (var prop in t.GetProperties(BindingFlags.Instance | BindingFlags.Public))
yield return prop;
t = t.BaseType;
}
}
private class PropertyInfoComparer : IEqualityComparer<PropertyInfo>
{
public static readonly PropertyInfoComparer Default = new PropertyInfoComparer();
public bool Equals(PropertyInfo x, PropertyInfo y)
{
return x.Name == y.Name;
}
public int GetHashCode(PropertyInfo obj)
{
return obj.Name.GetHashCode();
}
}
}
}
namespace Project
{
public abstract class DomainObject
{
public override bool Equals(object obj)
{
return DomainEqualityComparer.Default.Equals(this, obj);
}
public override int GetHashCode()
{
return DomainEqualityComparer.Default.GetHashCode(this);
}
public static bool operator ==(DomainObject x, DomainObject y)
{
return DomainEqualityComparer.Default.Equals(x, y);
}
public static bool operator !=(DomainObject x, DomainObject y)
{
return !(x == y);
}
}
}
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace Project
{
[TestClass]
public class DomainObjectTests
{
[TestMethod]
public void AddressEqualsWorksWithIdenticalAddresses()
{
var address = new Address("Address1", "Austin", "TX");
var address2 = new Address("Address1", "Austin", "TX");
Assert.IsTrue(address.Equals(address2));
}
[TestMethod]
public void AddressEqualsWorksWithNonIdenticalAddresses()
{
var address = new Address("Address1", "Austin", "TX");
var address2 = new Address("Address2", "Austin", "TX");
Assert.IsFalse(address.Equals(address2));
}
[TestMethod]
public void AddressEqualsWorksWithNulls()
{
var address = new Address(null, "Austin", "TX");
var address2 = new Address("Address2", "Austin", "TX");
Assert.IsFalse(address.Equals(address2));
}
[TestMethod]
public void AddressEqualsWorksWithNullsOnOtherObject()
{
var address = new Address("Address2", "Austin", "TX");
var address2 = new Address("Address2", null, "TX");
Assert.IsFalse(address.Equals(address2));
}
[TestMethod]
public void AddressEqualsIsReflexive()
{
var address = new Address("Address1", "Austin", "TX");
Assert.IsTrue(address.Equals(address));
}
[TestMethod]
public void AddressEqualsIsSymmetric()
{
var address = new Address("Address1", "Austin", "TX");
var address2 = new Address("Address2", "Austin", "TX");
Assert.IsFalse(address.Equals(address2));
Assert.IsFalse(address2.Equals(address));
}
[TestMethod]
public void AddressEqualsIsTransitive()
{
var address = new Address("Address1", "Austin", "TX");
var address2 = new Address("Address1", "Austin", "TX");
var address3 = new Address("Address1", "Austin", "TX");
Assert.IsTrue(address.Equals(address2));
Assert.IsTrue(address2.Equals(address3));
Assert.IsTrue(address.Equals(address3));
}
[TestMethod]
public void AddressOperatorsWork()
{
var address = new Address("Address1", "Austin", "TX");
var address2 = new Address("Address1", "Austin", "TX");
var address3 = new Address("Address2", "Austin", "TX");
Assert.IsTrue(address == address2);
Assert.IsTrue(address2 != address3);
}
[TestMethod]
public void DerivedTypesBehaveCorrectly()
{
var address = new Address("Address1", "Austin", "TX");
var address2 = new ExpandedAddress("Address1", "Apt 123", "Austin", "TX");
Assert.IsFalse(address.Equals(address2));
Assert.IsFalse(address == address2);
}
[TestMethod]
public void DerivedTypesBehaveCorrectlyWhenFieldsAreSame()
{
var address = new ExpandedAddress("Address1", "Apt 123", "Austin", "TX");
var address2 = new ExpandedAddress("Address1", "Apt 123", "Austin", "TX");
Assert.IsTrue(address.Equals(address2));
Assert.IsTrue(address == address2);
}
[TestMethod]
public void DerivedTypesBehaveCorrectlyWhenNewFieldsAreDifferent()
{
var address = new ExpandedAddress("Address1", "Apt 123", "Austin", "TX");
var address2 = new ExpandedAddress("Address1", "Apt 456", "Austin", "TX");
Assert.IsFalse(address.Equals(address2));
Assert.IsFalse(address == address2);
}
[TestMethod]
public void DerivedTypesBehaveCorrectlyWhenInheritedFieldsAreDifferent()
{
var address = new ExpandedAddress("Address1", "Apt 123", "Austin", "TX");
var address2 = new ExpandedAddress("Address2", "Apt 123", "Las Vegas", "NV");
Assert.IsFalse(address.Equals(address2));
Assert.IsFalse(address == address2);
}
[TestMethod]
public void EqualValueObjectsHaveSameHashCode()
{
var address = new Address("Address1", "Austin", "TX");
var address2 = new Address("Address1", "Austin", "TX");
Assert.AreEqual(address.GetHashCode(), address2.GetHashCode());
}
[TestMethod]
public void TransposedValuesGiveDifferentHashCodes()
{
var address = new Address(null, "Austin", "TX");
var address2 = new Address("TX", "Austin", null);
Assert.AreNotEqual(address.GetHashCode(), address2.GetHashCode());
}
[TestMethod]
public void UnequalValueObjectsHaveDifferentHashCodes()
{
var address = new Address("Address1", "Austin", "TX");
var address2 = new Address("Address2", "Austin", "TX");
Assert.AreNotEqual(address.GetHashCode(), address2.GetHashCode());
}
[TestMethod]
public void TransposedValuesOfFieldNamesGivesDifferentHashCodes()
{
var address = new Address("_city", null, null);
var address2 = new Address(null, "_address1", null);
Assert.AreNotEqual(address.GetHashCode(), address2.GetHashCode());
}
[TestMethod]
public void DerivedTypesHashCodesBehaveCorrectly()
{
var address = new ExpandedAddress("Address99999", "Apt 123", "New Orleans", "LA");
var address2 = new ExpandedAddress("Address1", "Apt 123", "Austin", "TX");
Assert.AreNotEqual(address.GetHashCode(), address2.GetHashCode());
}
private class Address : DomainObject
{
private readonly string _address1;
private readonly string _city;
private readonly string _state;
public Address(string address1, string city, string state)
{
_address1 = address1;
_city = city;
_state = state;
}
public string Address1
{
get { return _address1; }
}
public string City
{
get { return _city; }
}
public string State
{
get { return _state; }
}
}
private class ExpandedAddress : Address
{
private readonly string _address2;
public ExpandedAddress(string address1, string address2, string city, string state)
: base(address1, city, state)
{
_address2 = address2;
}
public string Address2
{
get { return _address2; }
}
}
}
}
using System;
using System.Collections;
using System.Reflection;
namespace Project
{
public class GenericEqualityComparer : IEqualityComparer
{
public static readonly GenericEqualityComparer Default = new GenericEqualityComparer();
public new bool Equals(object x, object y)
{
if (ReferenceEquals(x, y))
return true;
if (ReferenceEquals(x, null))
return false;
if (ReferenceEquals(null, y))
return false;
var t = x.GetType();
if (t != y.GetType())
return false;
return MakeFor(t).Equals(x, y);
}
public int GetHashCode(object obj)
{
if (obj == null)
throw new ArgumentNullException("obj");
return MakeFor(obj.GetType()).GetHashCode(obj);
}
private static IEqualityComparer MakeFor(Type t)
{
if (t == null || t == typeof (object) || t == typeof (ValueType))
return BaseEqualityComparer.Default;
return (IEqualityComparer) Activator.CreateInstance(typeof (GenericEqualityComparerFor<>).MakeGenericType(t));
}
private class GenericEqualityComparerFor<T> : IEqualityComparer
{
private static readonly IEqualityComparer Base = MakeFor(typeof (T).BaseType);
private static readonly FieldInfo[] Fields = typeof (T).GetFields(BindingFlags.Instance |
BindingFlags.NonPublic |
BindingFlags.Public);
public int GetHashCode(object obj)
{
var hashCode = 0;
foreach (var field in Fields)
{
var value = field.GetValue(obj);
hashCode = (hashCode*397) ^ (value == null ? 0 : value.GetHashCode());
}
return (hashCode*397) ^ Base.GetHashCode(obj);
}
public new bool Equals(object x, object y)
{
foreach (var field in Fields)
{
var value1 = field.GetValue(x);
var value2 = field.GetValue(y);
if (ReferenceEquals(value1, value2))
continue;
if (ReferenceEquals(value1, null))
return false;
if (ReferenceEquals(null, value2))
return false;
if (!value1.Equals(value2))
return false;
}
return Base.Equals(x, y);
}
}
private class BaseEqualityComparer : IEqualityComparer
{
public static readonly BaseEqualityComparer Default = new BaseEqualityComparer();
public new bool Equals(object x, object y)
{
return true;
}
public int GetHashCode(object obj)
{
return 0;
}
}
}
}
using System.Collections.Generic;
using System.Reflection;
namespace Project
{
public abstract class GenericObject<T>
{
public override bool Equals(object obj)
{
return GenericEqualityComparer.Default.Equals(this, obj as GenericObject<T>);
}
public override int GetHashCode()
{
return GenericEqualityComparer.Default.GetHashCode(this);
}
public static bool operator ==(GenericObject<T> x, GenericObject<T> y)
{
return GenericEqualityComparer.Default.Equals(x, y);
}
public static bool operator !=(GenericObject<T> x, GenericObject<T> y)
{
return !(x == y);
}
}
}
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace Project
{
[TestClass]
public class GenericObjectTests
{
[TestMethod]
public void AddressEqualsWorksWithIdenticalAddresses()
{
var address = new Address("Address1", "Austin", "TX");
var address2 = new Address("Address1", "Austin", "TX");
Assert.IsTrue(address.Equals(address2));
}
[TestMethod]
public void AddressEqualsWorksWithNonIdenticalAddresses()
{
var address = new Address("Address1", "Austin", "TX");
var address2 = new Address("Address2", "Austin", "TX");
Assert.IsFalse(address.Equals(address2));
}
[TestMethod]
public void AddressEqualsWorksWithNulls()
{
var address = new Address(null, "Austin", "TX");
var address2 = new Address("Address2", "Austin", "TX");
Assert.IsFalse(address.Equals(address2));
}
[TestMethod]
public void AddressEqualsWorksWithNullsOnOtherObject()
{
var address = new Address("Address2", "Austin", "TX");
var address2 = new Address("Address2", null, "TX");
Assert.IsFalse(address.Equals(address2));
}
[TestMethod]
public void AddressEqualsIsReflexive()
{
var address = new Address("Address1", "Austin", "TX");
Assert.IsTrue(address.Equals(address));
}
[TestMethod]
public void AddressEqualsIsSymmetric()
{
var address = new Address("Address1", "Austin", "TX");
var address2 = new Address("Address2", "Austin", "TX");
Assert.IsFalse(address.Equals(address2));
Assert.IsFalse(address2.Equals(address));
}
[TestMethod]
public void AddressEqualsIsTransitive()
{
var address = new Address("Address1", "Austin", "TX");
var address2 = new Address("Address1", "Austin", "TX");
var address3 = new Address("Address1", "Austin", "TX");
Assert.IsTrue(address.Equals(address2));
Assert.IsTrue(address2.Equals(address3));
Assert.IsTrue(address.Equals(address3));
}
[TestMethod]
public void AddressOperatorsWork()
{
var address = new Address("Address1", "Austin", "TX");
var address2 = new Address("Address1", "Austin", "TX");
var address3 = new Address("Address2", "Austin", "TX");
Assert.IsTrue(address == address2);
Assert.IsTrue(address2 != address3);
}
[TestMethod]
public void DerivedTypesBehaveCorrectly()
{
var address = new Address("Address1", "Austin", "TX");
var address2 = new ExpandedAddress("Address1", "Apt 123", "Austin", "TX");
Assert.IsFalse(address.Equals(address2));
Assert.IsFalse(address == address2);
}
[TestMethod]
public void DerivedTypesBehaveCorrectlyWhenFieldsAreSame()
{
var address = new ExpandedAddress("Address1", "Apt 123", "Austin", "TX");
var address2 = new ExpandedAddress("Address1", "Apt 123", "Austin", "TX");
Assert.IsTrue(address.Equals(address2));
Assert.IsTrue(address == address2);
}
[TestMethod]
public void DerivedTypesBehaveCorrectlyWhenNewFieldsAreDifferent()
{
var address = new ExpandedAddress("Address1", "Apt 123", "Austin", "TX");
var address2 = new ExpandedAddress("Address1", "Apt 456", "Austin", "TX");
Assert.IsFalse(address.Equals(address2));
Assert.IsFalse(address == address2);
}
[TestMethod]
public void DerivedTypesBehaveCorrectlyWhenInheritedFieldsAreDifferent()
{
var address = new ExpandedAddress("Address1", "Apt 123", "Austin", "TX");
var address2 = new ExpandedAddress("Address2", "Apt 123", "Las Vegas", "NV");
Assert.IsFalse(address.Equals(address2));
Assert.IsFalse(address == address2);
}
[TestMethod]
public void EqualGenericObjectsHaveSameHashCode()
{
var address = new Address("Address1", "Austin", "TX");
var address2 = new Address("Address1", "Austin", "TX");
Assert.AreEqual(address.GetHashCode(), address2.GetHashCode());
}
[TestMethod]
public void TransposedValuesGiveDifferentHashCodes()
{
var address = new Address(null, "Austin", "TX");
var address2 = new Address("TX", "Austin", null);
Assert.AreNotEqual(address.GetHashCode(), address2.GetHashCode());
}
[TestMethod]
public void UnequalGenericObjectsHaveDifferentHashCodes()
{
var address = new Address("Address1", "Austin", "TX");
var address2 = new Address("Address2", "Austin", "TX");
Assert.AreNotEqual(address.GetHashCode(), address2.GetHashCode());
}
[TestMethod]
public void TransposedValuesOfFieldNamesGivesDifferentHashCodes()
{
var address = new Address("_city", null, null);
var address2 = new Address(null, "_address1", null);
Assert.AreNotEqual(address.GetHashCode(), address2.GetHashCode());
}
[TestMethod]
public void DerivedTypesHashCodesBehaveCorrectly()
{
var address = new ExpandedAddress("Address99999", "Apt 123", "New Orleans", "LA");
var address2 = new ExpandedAddress("Address1", "Apt 123", "Austin", "TX");
Assert.AreNotEqual(address.GetHashCode(), address2.GetHashCode());
}
private class Address : GenericObject<Address>
{
private readonly string _address1;
private readonly string _city;
private readonly string _state;
public Address(string address1, string city, string state)
{
_address1 = address1;
_city = city;
_state = state;
}
public string Address1
{
get { return _address1; }
}
public string City
{
get { return _city; }
}
public string State
{
get { return _state; }
}
}
private class ExpandedAddress : Address
{
private readonly string _address2;
public ExpandedAddress(string address1, string address2, string city, string state)
: base(address1, city, state)
{
_address2 = address2;
}
public string Address2
{
get { return _address2; }
}
}
}
}
using System;
using System.Collections;
using System.Collections.Generic;
using System.Reflection;
namespace Project
{
public class HeirarchicalEqualityComparer : IEqualityComparer
{
public static readonly HeirarchicalEqualityComparer Default = new HeirarchicalEqualityComparer();
public new bool Equals(object x, object y)
{
if (ReferenceEquals(x, y))
return true;
if (ReferenceEquals(x, null))
return false;
if (ReferenceEquals(null, y))
return false;
var t = x.GetType();
if (t != y.GetType())
return false;
foreach (var field in GetFields(t))
{
var value1 = field.GetValue(x);
var value2 = field.GetValue(y);
if (ReferenceEquals(value1, value2))
continue;
if (ReferenceEquals(value1, null))
return false;
if (ReferenceEquals(null, value2))
return false;
if (!value1.Equals(value2))
return false;
}
return true;
}
public int GetHashCode(object obj)
{
if (obj == null)
throw new ArgumentNullException("obj");
var t = obj.GetType();
var hashCode = 0;
foreach (var field in GetFields(t))
{
var value = field.GetValue(obj);
hashCode = (hashCode*397) ^ (value == null ? 0 : value.GetHashCode());
}
return hashCode;
}
private static IEnumerable<FieldInfo> GetFields(Type t)
{
while (t != null && t != typeof (object) && t != typeof (ValueType))
{
foreach (var field in t.GetFields(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public))
yield return field;
t = t.BaseType;
}
}
}
}
namespace Project
{
public abstract class HeirarchicalObject
{
public override bool Equals(object obj)
{
return HeirarchicalEqualityComparer.Default.Equals(this, obj);
}
public override int GetHashCode()
{
return HeirarchicalEqualityComparer.Default.GetHashCode(this);
}
public static bool operator ==(HeirarchicalObject x, HeirarchicalObject y)
{
return HeirarchicalEqualityComparer.Default.Equals(x, y);
}
public static bool operator !=(HeirarchicalObject x, HeirarchicalObject y)
{
return !(x == y);
}
}
}
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace Project
{
[TestClass]
public class HeirarchicalObjectTests
{
[TestMethod]
public void AddressEqualsWorksWithIdenticalAddresses()
{
var address = new Address("Address1", "Austin", "TX");
var address2 = new Address("Address1", "Austin", "TX");
Assert.IsTrue(address.Equals(address2));
}
[TestMethod]
public void AddressEqualsWorksWithNonIdenticalAddresses()
{
var address = new Address("Address1", "Austin", "TX");
var address2 = new Address("Address2", "Austin", "TX");
Assert.IsFalse(address.Equals(address2));
}
[TestMethod]
public void AddressEqualsWorksWithNulls()
{
var address = new Address(null, "Austin", "TX");
var address2 = new Address("Address2", "Austin", "TX");
Assert.IsFalse(address.Equals(address2));
}
[TestMethod]
public void AddressEqualsWorksWithNullsOnOtherObject()
{
var address = new Address("Address2", "Austin", "TX");
var address2 = new Address("Address2", null, "TX");
Assert.IsFalse(address.Equals(address2));
}
[TestMethod]
public void AddressEqualsIsReflexive()
{
var address = new Address("Address1", "Austin", "TX");
Assert.IsTrue(address.Equals(address));
}
[TestMethod]
public void AddressEqualsIsSymmetric()
{
var address = new Address("Address1", "Austin", "TX");
var address2 = new Address("Address2", "Austin", "TX");
Assert.IsFalse(address.Equals(address2));
Assert.IsFalse(address2.Equals(address));
}
[TestMethod]
public void AddressEqualsIsTransitive()
{
var address = new Address("Address1", "Austin", "TX");
var address2 = new Address("Address1", "Austin", "TX");
var address3 = new Address("Address1", "Austin", "TX");
Assert.IsTrue(address.Equals(address2));
Assert.IsTrue(address2.Equals(address3));
Assert.IsTrue(address.Equals(address3));
}
[TestMethod]
public void AddressOperatorsWork()
{
var address = new Address("Address1", "Austin", "TX");
var address2 = new Address("Address1", "Austin", "TX");
var address3 = new Address("Address2", "Austin", "TX");
Assert.IsTrue(address == address2);
Assert.IsTrue(address2 != address3);
}
[TestMethod]
public void DerivedTypesBehaveCorrectly()
{
var address = new Address("Address1", "Austin", "TX");
var address2 = new ExpandedAddress("Address1", "Apt 123", "Austin", "TX");
Assert.IsFalse(address.Equals(address2));
Assert.IsFalse(address == address2);
}
[TestMethod]
public void DerivedTypesBehaveCorrectlyWhenFieldsAreSame()
{
var address = new ExpandedAddress("Address1", "Apt 123", "Austin", "TX");
var address2 = new ExpandedAddress("Address1", "Apt 123", "Austin", "TX");
Assert.IsTrue(address.Equals(address2));
Assert.IsTrue(address == address2);
}
[TestMethod]
public void DerivedTypesBehaveCorrectlyWhenNewFieldsAreDifferent()
{
var address = new ExpandedAddress("Address1", "Apt 123", "Austin", "TX");
var address2 = new ExpandedAddress("Address1", "Apt 456", "Austin", "TX");
Assert.IsFalse(address.Equals(address2));
Assert.IsFalse(address == address2);
}
[TestMethod]
public void DerivedTypesBehaveCorrectlyWhenInheritedFieldsAreDifferent()
{
var address = new ExpandedAddress("Address1", "Apt 123", "Austin", "TX");
var address2 = new ExpandedAddress("Address2", "Apt 123", "Las Vegas", "NV");
Assert.IsFalse(address.Equals(address2));
Assert.IsFalse(address == address2);
}
[TestMethod]
public void EqualValueObjectsHaveSameHashCode()
{
var address = new Address("Address1", "Austin", "TX");
var address2 = new Address("Address1", "Austin", "TX");
Assert.AreEqual(address.GetHashCode(), address2.GetHashCode());
}
[TestMethod]
public void TransposedValuesGiveDifferentHashCodes()
{
var address = new Address(null, "Austin", "TX");
var address2 = new Address("TX", "Austin", null);
Assert.AreNotEqual(address.GetHashCode(), address2.GetHashCode());
}
[TestMethod]
public void UnequalValueObjectsHaveDifferentHashCodes()
{
var address = new Address("Address1", "Austin", "TX");
var address2 = new Address("Address2", "Austin", "TX");
Assert.AreNotEqual(address.GetHashCode(), address2.GetHashCode());
}
[TestMethod]
public void TransposedValuesOfFieldNamesGivesDifferentHashCodes()
{
var address = new Address("_city", null, null);
var address2 = new Address(null, "_address1", null);
Assert.AreNotEqual(address.GetHashCode(), address2.GetHashCode());
}
[TestMethod]
public void DerivedTypesHashCodesBehaveCorrectly()
{
var address = new ExpandedAddress("Address99999", "Apt 123", "New Orleans", "LA");
var address2 = new ExpandedAddress("Address1", "Apt 123", "Austin", "TX");
Assert.AreNotEqual(address.GetHashCode(), address2.GetHashCode());
}
private class Address : HeirarchicalObject
{
private readonly string _address1;
private readonly string _city;
private readonly string _state;
public Address(string address1, string city, string state)
{
_address1 = address1;
_city = city;
_state = state;
}
public string Address1
{
get { return _address1; }
}
public string City
{
get { return _city; }
}
public string State
{
get { return _state; }
}
}
private class ExpandedAddress : Address
{
private readonly string _address2;
public ExpandedAddress(string address1, string address2, string city, string state)
: base(address1, city, state)
{
_address2 = address2;
}
public string Address2
{
get { return _address2; }
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment