Подобные темы, которые обращаются к этому, возможно, существуют на SO, но я их не понимаю: (
У меня есть такой сценарий:
internal static void AddToListBox(ListBox lb, User usr)
{
if (CanAddUser(lb, usr))
lb.Items.Add(usr);
}
static bool CanAddUser(ListBox lb, User usr)
{
foreach (User u in lb.Items)
{
if (u.Id == usr.Id)
return false;
}
return true;
}
Теперь у меня есть другой точно такой же сценарий, как этот:
internal static void AddToList(List<User> lstUser, User usr)
{
if (CanAddUser(lstUser, usr))
lstUser.Add(usr);
}
static bool CanAddUser(List<User> lstUser, User usr)
{
foreach (User u in lstUser)
{
if (u.Id == usr.Id)
return false;
}
return true;
}
В основном оба набора делают одно и то же. Мне было любопытно, если бы я мог сделать это одной функцией, но это только так, как это работает, что делает код более многословным:
internal static void AddToList(IEnumerable enumerable, User usr)
{
if (enumerable is ListBox.ObjectCollection)
{
if (CanAddUser(enumerable, usr))
((ListBox.ObjectCollection)enumerable).Add(usr);
}
else if (enumerable is List<User>)
{
if (CanAddUser(enumerable, usr))
((List<User>)enumerable).Add(usr);
}
}
internal static bool CanAddUser(IEnumerable enumerable, User usr)
{
foreach (User u in enumerable)
{
if (u.Id == usr.Id)
return false;
}
return true;
}
Как я уже сказал, это работает, но блок if else делает его уродливым и убивает идею сокращения кода. Могу ли я сделать что-то вроде этого:
internal static void AddToList(IEnumerable enumerable, User usr)
{
if (CanAddUser(enumerable, usr))
((whatever the type is passed, just find it yourself)enumerable).Add(usr);
}
??
Я пытался
internal static void AddToList(IEnumerable enumerable, User usr)
{
if (CanAddUser(enumerable, usr))
((enumerable.GetType()) / (typeof(enumerable))enumerable).Add(usr);
//both which wont compile.
}
Так как это сделать? Разве невозможно привести IEnumerable
к неизвестному типу? Или решение будет слишком грязным, чтобы я отказался от плана? Что-нибудь может быть сделано, если я знаю, что переданный IEnumerable
будет только типа ListBox.ObjectCollection
и List<User>
, кроме логики if else? Извините за длинный кусок, просто нужно объяснить мое требование ..
ОБНОВЛЕНИЕ: Ответ StriplingWarrior обязательно решит мою проблему, но мне интересно, как бы объект был приведен к своему первоначальному типу, если бы я реализовал последнюю функцию. Возможно, через отражение или что-то. Я отмечу решение этого как ответ. Спасибо @StriplingWarrior еще раз.
ОБНОВЛЕНИЕ 2:
Чтобы было понятнее, забудьте обо всем, что было опубликовано выше. Предположим, у меня есть функция, как показано ниже. Admonish()
- это метод расширения, который я определил для объектов типа List<Naughty>
и List<Obedient>
отдельно. Как я смогу написать только одну Sanitize
функцию и передать ей List<Naughty
или List<Obedient
? Как это:
internal static void Sanitize(IEnumerable enumerable)
{
enumerable.Admonish();
}
??
Я знаю, что могу сделать это:
internal static void Sanitize(IEnumerable enumerable)
{
if (enumarable is List<Naughty>)
((List<Naughty>)enumerable).Admonish();
if (enumarable is List<Obedient>)
((List<Obedient>)enumerable).Admonish();
}
Как я смогу сделать это за один раз, например:
internal static void Sanitize(IEnumerable enumerable)
{
((Determine type here, but how??)enumerable).Admonish();
}
Надеюсь, вопрос ясен. Я не ищу решение для особого случая, но общее решение, чтобы получить тип во время выполнения , чтобы объект мог быть приведен к его типу !!