C # и массивы анонимных объектов - PullRequest
46 голосов
/ 10 января 2010

Что означает такое выражение?

obj.DataSource = new[]
{
    new {Text = "Silverlight", Count = 10, Link="/Tags/Silverlight" },
    new {Text = "IIS 7", Count = 11, Link="http://iis.net" },
    new {Text = "IE 8", Count = 12, Link="/Tags/IE8" },
    new {Text = "C#", Count = 13, Link="/Tags/C#" },
    new {Text = "Azure", Count = 13, Link="?Tag=Azure" }
};

Особенно эти строки: new {Text = "IIS 7" ...}

Как я могу создать такой массив вручную, чтобы соответствовать этому источнику данных.

Ответы [ 6 ]

58 голосов
/ 10 января 2010

Во-первых, давайте немного переформатируем этот код :

obj.DataSource = new[]
{
    new {  Text = "Silverlight",  Count = 10,  Link = "/Tags/Silverlight"  },
    new {  Text = "IIS 7",        Count = 11,  Link = "http://iis.net"     }, 
    new {  Text = "IE 8",         Count = 12,  Link = "/Tags/IE8"          }, 
    new {  Text = "C#",           Count = 13,  Link = "/Tags/C#"           },
    new {  Text = "Azure",        Count = 13,  Link = "?Tag=Azure"         } 
};

Это не похоже на многомерный массив, а скорее на массив из 5 объектов. Эти объекты внутри массива имеют анонимный тип , созданный и инициализированный с использованием new { ... }.

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

39 голосов
/ 10 января 2010

Это не многомерный массив.Это массив объектов, которые были созданы с использованием инициализаторов объектов с анонимными типами .

4 голосов
/ 10 января 2010

Похоже на массив анонимных типов.

http://msdn.microsoft.com/en-us/library/bb397696.aspx

3 голосов
/ 10 января 2010

Просто добавим: анонимные типы преобразуются компилятором в реальный объект. Таким образом, код будет изменен на что-то эквивалентное этому (НАМНОГО упрощено, только чтобы показать, что компилятор создаст реальный класс):

internal sealed class AnonymousClass1
{
    internal string Text { get; set; }
    internal int Count { get; set; }
    internal string Link { get; set; }
}

И ваш код будет изменен на:

obj.DataSource = new AnonymousClass1[]
{
    new AnonymousClass1 {Text = "Silverlight", Count = 10, Link="/Tags/Silverlight" },
    new AnonymousClass1 {Text = "IIS 7", Count = 11, Link="http://iis.net" },
    new AnonymousClass1 {Text = "IE 8", Count = 12, Link="/Tags/IE8" },
    new AnonymousClass1 {Text = "C#", Count = 13, Link="/Tags/C#" },
    new AnonymousClass1 {Text = "Azure", Count = 13, Link="?Tag=Azure" }
};

В одной из моих программ у меня есть такой код (упрощенно!):

var myObjects = new []{
    new { Id = Guid.NewGuid(), Title = "Some Title", Description = string.Empty },
    new { Id = Guid.NewGuid(), Title = "Another Title", Description = string.Empty },
    new { Id = Guid.NewGuid(), Title = "Number 3", Description = "Better than No2, but not much" }
}

foreach(var myObject in myObjects) {
    DoSomeThingWith(myObject.Title);
}

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

2 голосов
/ 10 января 2010

Создает новый массив объектов, содержащий группу анонимных объектов.

new {Text = "Azure", Count = 13, Link="?Tag=Azure" }

не создает хеш, подобный похожему синтаксису, скажем, в php, а скорее представляет собой реальный объект со свойствами Test, Count и Link.

Хороший праймер для анонимных объектов можно найти здесь

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

string text = "Azure";
int count = 13;
string link =  "?Tag=Azure";
new {Text = text, Count = count, Link=link }
1 голос
/ 10 января 2010

Чтобы вернуть такой массив из функции, которую я использовал:

public object GetAnonymousArray()
{
    var tbl = new List<object>();
    while (___)
    {
        //fill array in cycle
        tbl.Add(new {Text = someString, Count = someInt, Link = link});
    }  
    return tbl;
}
...