Приведите анонимные типы в объект и получите одно поле - PullRequest
5 голосов
/ 01 августа 2011

Я использую C # asp.net4.

У меня есть метод для заполнения Repeater анонимными типами (поля: Title, CategoryId), внутри Repeater я также разместил метку:

        var parentCategories = from c in context.CmsCategories
                               where c.CategoryNodeLevel == 1
                               select new { c.Title, c.CategoryId };
        uxRepeter.DataSource = parentCategories;
        uxRepeter.DataBind();

Мне нужно изменить свойства текста для каждой метки внутри моего повторителя при событии повторителя ItemDataBound

   protected void uxRepeter_ItemDataBound(object sender, RepeaterItemEventArgs e)
    {
        HyperLink link = (HyperLink)e.Item.FindControl("uxLabel");
        uxLabel.Text = // How to do here!!!!!!!! 
    }

Поэтому мне нужно установить свойства для Label.Text, используя e.Item (или лучший способесли есть).

Моя проблема: я не могу CAST e.Item (заголовок поля анонимного типа) и установить его в качестве текстового свойства для моей метки.

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

Мой вопрос:

Как преобразовать и получить интересующее меня поле?Спасибо за ваше время на это?

РЕДАКТИРОВАТЬ: НЕКОТОРЫЕ ОШИБКИ Я ПОЛУЧУ:

Unable to cast object of type '<>f__AnonymousType0`2[System.String,System.Int32]' to type 'System.String'.

Ответы [ 4 ]

10 голосов
/ 01 августа 2011

Варианты, которые предлагает Джозеф, хороши, но - это ужасный способ сделать это. Это несколько хрупко, так как полагается на указание анонимного типа в точно одинаково в двух местах. Вот и мы:

public static T CastByExample<T>(object input, T example)
{
    return (T) input;
}

Тогда:

object item = ...; // However you get the value from the control

// Specify the "example" using the same property names, types and order
// as elsewhere.
var cast = CastByExample(item, new { Title = default(string),
                                     CategoryId = default(int) } );
var result = cast.Title;

РЕДАКТИРОВАТЬ: дополнительная складка - два выражения создания анонимного типа должны находиться в одной сборке (проекте). Извините, что забыл упомянуть об этом раньше.

4 голосов
/ 01 августа 2011

Вы можете использовать dynamic в этом случае.Я думаю, что код будет:

protected void uxRepeter_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
    dynamic link = (dynamic)e.Item.FindControl("uxLabel");
    uxLabel.Text = link.Title; //since 'link' is a dynamic now, the compiler won't check for the Title property's existence, until runtime.
}
4 голосов
/ 01 августа 2011

Вы не можете привести анонимный тип ни к чему, потому что у вас буквально нет типа, к которому вы можете привести его, как вы уже указали.

Так что у вас действительно есть два варианта.

  1. Не приводите к анонимному типу, а скорее к известному типу, который вы создаете только для обработки этого сценария или
  2. назначить динамическую переменную элементу и использовать вместо нее динамические свойства

Пример 1:

var parentCategories = from c in context.CmsCategories
    where c.CategoryNodeLevel == 1
    select new RepeaterViewModel { c.Title, c.CategoryId };

Пример 2: (также я думаю, что вы последняя строка, которую вы хотели назначить для ссылки)

protected void uxRepeter_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
    HyperLink link = (HyperLink)e.Item.FindControl("uxLabel");
    dynamic iCanUseTitleHere = e.Item;
    link.Text = iCanUseTitleHere.Title; //no compilation issue here
}
0 голосов
/ 25 июля 2014

Разве вы не можете просто разыграть (typeof(new { Title = "", CategoryID = 0 }))?

...