c # анонимный объект, почему только иногда содержит определения полей? - PullRequest
0 голосов
/ 14 мая 2019

Почему я могу немедленно получить доступ к свойствам анонимного объекта здесь:

    public object ComputeStats()
    {
        var obj = new
        {
            avg = 2,
            hi = 3,
            lo = 1
        };

        Console.WriteLine(obj.avg);

        return obj;
    }

Но не здесь (ошибка компилятора 'object' не содержит определения для 'avg'):

    public void DisplayStats()
    {
        object stats = ComputeStats();
        Console.WriteLine("average: " + stats.avg);
    }

Обходным решением будет объявить stats как dynamic, но большинство скажет просто создать класс / тип для этого объекта.Я бы предпочел использовать анонимный объект, но не хочу начинать использовать динамические только для удобства.

1 Ответ

1 голос
/ 14 мая 2019

Это не относится только к анонимным типам. Все наследуется от object, что означает, что вы можете неявно приводить что-либо как object.

Вызов метода, который возвращает анонимный тип, и присвоение его переменной, объявленной как object, аналогично выполнению этого:

object obj = new { avg = 2, hi = 3, lo = 1 };

object не имеет таких свойств, как avg, hi и т. Д., Поэтому Visual Studio не отображает их, и при вводе они не будут компилироваться.

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

var s = "Hello!";
object o = s;

Там только один string. И s, и o относятся к string. Но s разыгрывается как string, а o - как object.

.

Итак, вы можете сделать это:

var s = "Hello!";
object o = s;
var l = s.Length;

... но вы не можете сделать это:

var s = "Hello!";
object o = s;
var l = o.Length; // object doesn't have a Length property.

Если вы сделаете это:

    var obj = new { avg = 2, hi = 3, lo = 1};

... использование var означает, что тип выведен. Что бы вы ни присваивали, это тип. В этом случае за кулисами компилятор фактически создает новый тип, поэтому он ведет себя так, как будто вы определили тип с этими свойствами.

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

...