Где () с Replace () в Dictionary.Where (p => p.Key is T) - PullRequest
2 голосов
/ 18 мая 2010

У меня есть System.Collections.Generic.Dictionary<System.Web.UI.Control, object>, где все ключи могут быть либо типа System.Web.UI.WebControls.HyperLink, либо типа System.Web.UI.WebControls.Label.

Я хочу изменить Text свойство каждого элемента управления. Поскольку HyperLink не реализует (почему ?!) ITextControl, мне нужно явно разыграть Label или HyperLink:

Dictionary<Control,object> dic = ..

dic
  .Where(p => p.Key is HyperLink)
  .ForEach(c => ((HyperLink)c).Text = "something")

dic
  .Where(p => p.Key is Label)
  .ForEach(c => ((Label)c).Text = "something")

Есть ли способы обойти такой подход?

Ответы [ 6 ]

5 голосов
/ 18 мая 2010

Чуть более элегантно, но с сохранением проблемы:

foreach (HyperLink c in dic.Keys.OfType<HyperLink>())
{
    c.Text = "something";
}

foreach (Label c in dic.Keys.OfType<Label>())
{
    c.Text = "something";
}
3 голосов
/ 18 мая 2010

Вы можете создать класс, производный от HyperLink, и позволить вашему классу наследовать от ITextControl. Должно быть понятно, куда идти дальше ...

2 голосов
/ 18 мая 2010

Этот способ выглядит уродливее и неуклюже, но, по крайней мере, вы перечисляете по словарю только один раз:

dic
  .ForEach(
    c => {
      var clink = c as Hyperlink;
      if (clink != null) {
        clink.Text = "something";
        return;
      }

      var clabel = c as Label;
      if (clabel != null) {
        clabel.Text = "something";
        return;
      }
    }
  );
2 голосов
/ 18 мая 2010
dic.ForEach(c => c.Key.GetType()
    .GetProperty("Text")
    .SetValue(c.Key, "Something",null));

Тотальный взлом, возможно, не эффективен, но он должен работать ....

РЕДАКТИРОВАТЬ: Еще одна вещь, которую стоит упомянуть, если вы используете .Net 4, вы можете использовать утку набрав:

dic.ForEach(kvp => ((dynamic)kvp.Key).Text = "Something");
1 голос
/ 19 мая 2010

То же, что и ответ Дана Тао - только для минимальной неуклюжести.

foreach(Control c in dic.Keys)
{
  HyperLink clink = c as Hyperlink; 
  if (clink != null)
  { 
    clink.Text = "something";
    continue;
  } 

  Label clabel = c as Label; 
  if (clabel != null)
  { 
    clabel.Text = "something";
    continue;
  } 
} 
0 голосов
/ 18 мая 2010

Если текст не является свойством элемента управления, будет более понятно, если вы укажете его в отдельных операторах. Я бы не стал объединять их просто потому, что они оба используют слово «Текст» для определения свойства.

...