那个设定
我有一个原型类TypedString<T>
,它试图“强类型”(可疑的含义)某个类别的字符串。它使用 C#-analogue 的奇怪重复模板模式 (CRTP)。
class TypedString<T>
public abstract class TypedString<T>
: IComparable<T>
, IEquatable<T>
where T : TypedString<T>
{
public string Value { get; private set; }
protected virtual StringComparison ComparisonType
{
get { return StringComparison.Ordinal; }
}
protected TypedString(string value)
{
if (value == null)
throw new ArgumentNullException("value");
this.Value = Parse(value);
}
//May throw FormatException
protected virtual string Parse(string value)
{
return value;
}
public int CompareTo(T other)
{
return string.Compare(this.Value, other.Value, ComparisonType);
}
public bool Equals(T other)
{
return string.Equals(this.Value, other.Value, ComparisonType);
}
public override bool Equals(object obj)
{
return obj is T && Equals(obj as T);
}
public override int GetHashCode()
{
return Value.GetHashCode();
}
public override string ToString()
{
return Value;
}
}
TypedString<T>
在整个项目中定义一堆不同的“字符串类别”时,该类现在可用于消除代码重复。此类的一个简单用法示例是定义一个Username
类:
class Username
(例子)
public class Username : TypedString<Username>
{
public Username(string value)
: base(value)
{
}
protected override string Parse(string value)
{
if (!value.Any())
throw new FormatException("Username must contain at least one character.");
if (!value.All(char.IsLetterOrDigit))
throw new FormatException("Username may only contain letters and digits.");
return value;
}
}
现在,这让我可以Username
在整个项目中使用该类,而不必检查用户名的格式是否正确 - 如果我有一个类型的表达式或变量Username
,则可以保证它是正确的(或为空)。
方案 1
string GetUserRootDirectory(Username user)
{
if (user == null)
throw new ArgumentNullException("user");
return Path.Combine(UsersDirectory, user.ToString());
}
我不必担心这里用户字符串的格式 - 我已经知道它的类型本质上是正确的。
方案 2
IEnumerable<Username> GetFriends(Username user)
{
//...
}
在这里,调用者仅根据类型就知道它得到了什么作为返回。需要IEnumerable<string>
阅读方法或文档的详细信息。更糟糕的是,如果有人要更改其实现,GetFriends
从而引入错误并产生无效的用户名字符串,则该错误可能会默默地传播给方法的调用者并造成各种破坏。这个打字很好的版本可以防止这种情况。
方案 3
System.Uri
是 .NET 中的一个类的示例,它只不过是包装了一个字符串,该字符串具有大量格式约束和用于访问有用部分的辅助属性/方法。所以这是一个证据,表明这种方法并不完全疯狂。
问题
我想这种事情以前已经做过了。我已经看到了这种方法的好处,不需要再说服自己了。
我可能会遗漏一个缺点吗?
有没有办法这以后会回来咬我?