Functional Programming - قسمت پنجم - وسواس استفاده از نوع های اولیه
نویسنده: سعید صالحی
تاریخ: ۱۳۹۹/۰۱/۱۳ ۲۰:۲۵
آدرس: www.dntips.ir
| مطالب | ۳۶۹۴ |
| نویسندگان | ۲۷۶ |
| گروههای مطالب | ۱۰۲۴ |
| نقشههای راه | ۱۱۹ |
| دورهها | ۱۴ |
| اشتراکها | ۱۷۹۱۴ |
public class UserFactory
{
public User CreateUser(string email) {
return new User(email);
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
namespace ValueOf
{
public class ValueOf<TValue, TThis> where TThis : ValueOf<TValue, TThis>, new()
{
private static readonly Func<TThis> Factory;
/// <summary>
/// WARNING - THIS FEATURE IS EXPERIMENTAL. I may change it to do
/// validation in a different way.
/// Right now, override this method, and throw any exceptions you need to.
/// Access this.Value to check the value
/// </summary>
protected virtual void Validate()
{
}
static ValueOf()
{
ConstructorInfo ctor = typeof(TThis)
.GetTypeInfo()
.DeclaredConstructors
.First();
var argsExp = new Expression[0];
NewExpression newExp = Expression.New(ctor, argsExp);
LambdaExpression lambda = Expression.Lambda(typeof(Func<TThis>), newExp);
Factory = (Func<TThis>)lambda.Compile();
}
public TValue Value { get; protected set; }
public static TThis From(TValue item)
{
TThis x = Factory();
x.Value = item;
x.Validate();
return x;
}
protected virtual bool Equals(ValueOf<TValue, TThis> other)
{
return EqualityComparer<TValue>.Default.Equals(Value, other.Value);
}
public override bool Equals(object obj)
{
if (obj is null)
return false;
if (ReferenceEquals(this, obj))
return true;
return obj.GetType() == GetType() && Equals((ValueOf<TValue, TThis>)obj);
}
public override int GetHashCode()
{
return EqualityComparer<TValue>.Default.GetHashCode(Value);
}
public static bool operator ==(ValueOf<TValue, TThis> a, ValueOf<TValue, TThis> b)
{
if (a is null && b is null)
return true;
if (a is null || b is null)
return false;
return a.Equals(b);
}
public static bool operator !=(ValueOf<TValue, TThis> a, ValueOf<TValue, TThis> b)
{
return !(a == b);
}
public override string ToString()
{
return Value.ToString();
}
}
} public class EmailAddress : ValueOf<string, EmailAddress> { } EmailAddress emailAddress = EmailAddress.From("foo@bar.com"); public class Address : ValueOf<(string firstLine, string secondLine, Postcode postcode), Address> { }