2009-03-09 3 views
1

У меня есть метод, который в настоящее время занимает 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 используется другой программой (в качестве примера мы будем использовать приведенный выше метод).

Дело в том, что теперь мне нужно иметь тот же код, за исключением поля «Пароль» вместо поля «Пин» (есть веская причина иметь оба поля).

Вместо того, чтобы просто создавать другой метод с похожим именем, я бы предпочел реорганизовать код, чтобы полностью удалить конкретный код BO из этого класса и сделать так, чтобы решение о том, какой класс/члены использовать сделаны не в самом методе, а в коде, вызывающем его.

Один из вариантов - передать IDictionary и использовать метод Linq ToDictionary для создания словаря «на лету» в вызывающем коде. Это, однако, потеряло бы порядок предметов (что было бы неплохо, но не обязательно для сохранения). Я мог бы использовать IList или что-то в этом роде, но было бы труднее преобразовать IList.

Есть ли у кого-нибудь хорошие предложения о том, как это сделать?

P.S. Если у кого-то есть лучшее представление о том, как назвать этот пост, не стесняйтесь идти на него.

ответ

2

Вы также можете использовать выражение:

WriteUsers(IList<T> users, u => u.Username, u => u.Password); 

если вы используете Net 3.5.

+0

думаю это может сработать. Я собираюсь проверить это. Благодаря! –

2

Непонятно точно что вам нужно делать со строками после форматирования. Вы могли бы сделать метод взять IEnumerable<string>, а затем сделать код вызова:

WriteUsers(users.Select(user => string.Format("{0}: {1}", 
               users.Username, users.Pin))); 

ли это работает для вас или нет, будет зависеть от деталей.

+0

В моей я должен использовать имена пользователей/контакты в разных местах и ​​в разных форматах, поэтому я не думаю, что это сработает. Я отредактирую сообщение, чтобы сделать это более понятным. Спасибо хоть! –

1

Во-первых, для удобства использования я рекомендую переключить ваш IList на IEnumerable. Если вы не выполняете какую-либо другую логику, требующую списка, она открывает ваш класс для использования другими пользователями и не имеет недостатков.

Если вы хотите полностью исключить выбор того, что печатается из вашего класса, я могу придумать пару вариантов.

Один (хотя потенциально менее полезный) будет использовать отражение. Если перф. не является большой проблемой, вы можете реорганизовывать это иметь что-то вроде:

WriteElements (IEnumerable элементов, Params строка [] 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); 
Смежные вопросы