Как я могу определить анонимный тип? - PullRequest
1 голос
/ 10 сентября 2011

У меня есть переменная анонимного типа, которую я заполняю следующим образом (у меня есть две переменные jsonDataCache и jsonData, но я хочу иметь только одну, например, jsonData):

 var jsonData = new
            {
                total = totalPages,
                page = page,
                records = totalRecords,

                rows = (from b in myData
                select new
                        {
                        //do things
                        }).ToArray()
             };
return Json(jsonData, JsonRequestBehavior.AllowGet);

Но если я хочу сначала определить эту переменную, прежде чем заполнять ее, в основном я хочу сделать что-то подобное:

var jsonData = null;   

//check if jsonData in cache and if it is return Json(jsonData, JsonRequestBehavior.AllowGet);

jsonData = new
                {
                    total = totalPages,
                    page = page,
                    records = totalRecords,

                    rows = (from b in myData
                    select new
                            {
                            //do things
                            }).ToArray()
                 };
//put jsonData in cache by key

return Json(jsonData, JsonRequestBehavior.AllowGet);

Как я могу это сделать?

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

Вот как я сейчас это сделал:

public virtual JsonResult GetSomething(int id, int type)
{
   string keyPrefix = GetKeyPrefix(id, type);

   var jsonDataCache = CacheManager.Get<object>(keyPrefix);   

    if(jsonDataCache != null)
      return Json(jsonDataCache, JsonRequestBehavior.AllowGet);

    var myData = GetFromDataase();

    var jsonData = new
                    {
                        total = totalPages,
                        page = page,
                        records = totalRecords,

                        rows = (from b in myData
                        select new
                                {
                                //do things
                                }).ToArray()
                     };

    CacheManager.Set<object>(keyPrefix, jsonData);

    return Json(jsonData, JsonRequestBehavior.AllowGet);
}

UPDATE: После всей вашей помощи я думаю, что это должно быть что-то вроде этого, надеюсь, это правильный путь:

public virtual JsonResult GetSomething(int id, int type)
{
   string keyPrefix = GetKeyPrefix(id, type);

   var jsonData = CacheManager.Get<object>(keyPrefix);   

    if(jsonData != null)
      return Json(jsonData , JsonRequestBehavior.AllowGet);

    var myData = GetFromDataase();

    jsonData = new
                    {
                        total = totalPages,
                        page = page,
                        records = totalRecords,

                        rows = (from b in myData
                        select new
                                {
                                //do things
                                }).ToArray()
                     };

    CacheManager.Set<object>(keyPrefix, jsonData);

    return Json(jsonData, JsonRequestBehavior.AllowGet);
}               

Ответы [ 3 ]

3 голосов
/ 10 сентября 2011

Ну, вы можете создать его «на примере» - с теми же именами и типами свойств, в том же порядке, только с фиктивными значениями. Например:

var jsonData = new { total = 0, page = 0, records = 0,
                     rows = new[] { new { dummy = "" } };

Было неясно, что вы хотели сделать для вложенного анонимного типа, поэтому я просто создал его со строковым свойством, которое называется dummy.

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

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

2 голосов
/ 10 сентября 2011

Вы не можете сделать это (и инициализировать в ноль), за исключением некоторых действительно противных и уродливых тактик «на примере» с помощью общих методов. Переменные для анонимных типов могут быть объявлены только вместе с инициализацией (кроме как в качестве параметра универсального типа).

Однако кажется маловероятным, что вам это действительно нужно здесь. Действительно,

object jsonData;

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

1 голос
/ 10 сентября 2011

Неясно, почему вы хотите это сделать, но вот один из способов:

Вы можете создать свой объект как тип object или dynamic

object foo = null;

foo = new {
 bar = "bar"
};

Обновление:

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

Лично я использую System.Web.Caching.Cache и у меня есть метод расширения, который проверяет кэш для вашего элемента (на основе ключа кэша) или выполняет ваш метод для извлечения данных.

public static T GetOrStore<T>(this Cache cache, string key, Func<T> generator)
        {
            var result = cache.Get(key);
            if(result == null)
            {
                result = generator();
                cache.Insert(key,result);
            }

            return (T) result;
        }

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

var jsonData = Cache.GetOrStore("jsonData", Foo);

где:

private static string Foo()
{
   return new {[...]}
}
...