[英]How do I make this class more reusable? (specific example inside)
我有一个当前将 IList 作为参数的方法,其中 UserBO 类似于以下内容:
public class UserBO {
public string Username { get; set; }
public string Password { get; set; }
public string Pin { get; set; }
}
public class SomeClass {
// An example method giving the basic idea of what I need to do
public void WriteUsers(IList<UserBO> users) {
// Do stuff with users
for (var user in users) {
Console.WriteLine(String.Format(User: {0}: {1}, users.Username, Hash(users.Pin)); // Now needs to optionally be users.Password
}
}
private string Hash(string pin) {
return // Hashed Pin
}
}
然后,此方法使用用户名/Pin 对创建一些 XML 供另一个程序使用(我们将以上述方法为例)。
问题是,现在我需要能够生成相同的代码,除了使用 Password 字段而不是 Pin 字段(有两个字段的充分理由)。
我宁愿重构代码,以便完全从此 class 中删除 BO 特定代码,而不是仅仅创建另一个具有相似名称的方法,并做出关于使用哪些类/成员的决定不在方法本身,但调用它的代码。
一种选择是传递一个 IDictionary 并使用 Linq ToDictionary 方法在调用代码中动态创建字典。 但是,这会丢失物品的顺序(这很好但不是必须保留)。 我可以使用 IList 或其他东西,但是将 IList 转换为更困难。
有人对如何做到这一点有任何好的建议吗?
PS 如果有人对如何为这篇文章命名有更好的想法,请随时在上面写一个 go。
目前尚不清楚格式化后需要对字符串做什么。 您可以使该方法采用IEnumerable<string>
,然后进行调用代码:
WriteUsers(users.Select(user => string.Format("{0}: {1}",
users.Username, users.Pin)));
这是否适合您将取决于细节。
您还可以使用表达式:
WriteUsers(IList<T> users, u => u.Username, u => u.Password);
如果您使用的是 Net 3.5。
首先,为了可用性,我建议将您的 IList 切换为 IEnumerable。 如果您不执行任何需要列表的其他逻辑,它会打开您的 class 以供更多用户使用,并且没有缺点。
如果您想完全消除从 class 打印的内容的选择,我可以想到几个选项。
一种(尽管可能不太有用)是使用反射。 如果性能。 不是一个大问题,您可以将其重构为:
WriteElements(IEnumerable 元素,参数 string[] propertiesToWrite)
然后,您可以重构该方法,以便它使用反射从 T 的类型说明符中获取属性,并写出任意数量的属性。 然后调用者会这样做:
WriteElements(listOfUsers, "Username", "Password");
第二个可能更清洁的选择是重构它以采取:
WriteElements(IEnumerable<UserBO>, Func<UserBO,string>);
然后你可以调用它:
// Call using password
WriteElements(listOfUsers, user => user.Password);
// or call using pin
WriteElements(listOfUsers, user => user.Pin);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.