Czy istnieje sztuczka w tworzeniu ogólnej listy anonimowego typu?
Czasami muszę użyć krotki, na przykład mam listę czołgów i ich docelowych czołgów (gonią za nimi lub coś w tym stylu): {]}
List<Tuple<Tank,Tank>> mylist = new List<Tuple<Tank,Tank>>();
I kiedy iteruję nad listą, uzyskuję do nich dostęp przez
mylist[i].item1 ...
mylist[i].item2 ...
Jest to bardzo mylące i zawsze zapominam, co to jest item1 i co to jest item2, gdybym mógł uzyskać do nich dostęp przez:
mylist[i].AttackingTank...
mylist[i].TargetTank...
Byłoby o wiele jaśniejsze, czy istnieje sposób, aby to zrobić bez definiowania klasy: {]}
MyTuple
{
public Tank AttackingTank;
public Tank TargetTank;
}
Chcę uniknąć definiowania tej klasy, ponieważ wtedy musiałbym zdefiniować wiele różnych klas w różnych scenariuszach, Czy Mogę zrobić jakiś "trick" i uczynić to anonimowym.
Coś w stylu:
var k = new {Name = "me", phone = 123};
mylist.Add(k);
Problem oczywiście, że nie mam typu do przekazania do listy, gdy ją zdefiniuję
9 answers
Możesz utworzyć pustą listę anonimowych typów, a następnie użyć jej, korzystając z pełnej inteligencji i kontroli kompilacji:
var list = Enumerable.Empty<object>()
.Select(r => new {A = 0, B = 0}) // prototype of anonymous type
.ToList();
list.Add(new { A = 4, B = 5 }); // adding actual values
Console.Write(list[0].A);
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-04-01 18:59:20
Przydałby się List<dynamic>
.
var myList = new List<dynamic>();
myList.Add(new {Tank = new Tank(), AttackingTank = new Tank()});
Console.WriteLine("AttackingTank: {0}", myList[0].AttackingTank);
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-04-01 18:58:49
Oto hack:
var myList = Enumerable.Empty<int>()
.Select(dummy => new { AttackingTank = default(Tank), TargetTank = default(Tank), })
.ToList();
Jeśli Tank
jest typem klasy, możesz napisać (Tank)null
zamiast default(Tank)
. Możesz również użyć jakiegoś Tank
przykładu, który masz pod ręką.
EDIT:
Lub:
var myList = Enumerable.Repeat(
new { AttackingTank = default(Tank), TargetTank = default(Tank), },
0).ToList();
Jeśli stworzysz metodę generyczną, nie będziesz musiał używać Enumerable.Empty
. Może tak być:
static List<TAnon> GetEmptyListWithAnonType<TAnon>(TAnon dummyParameter)
{
return new List<TAnon>();
}
Ma być wywoływana z TAnon
wnioskowane z użycia, oczywiście, jak w:
var myList = GetEmptyListWithAnonType(new { AttackingTank = default(Tank), TargetTank = default(Tank), });
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-10-21 20:40:33
Możesz po prostu mieć metodę generyczną, która pobiera params
i zwraca ją:
public static IList<T> ToAnonymousList<T>(params T[] items)
{
return items;
}
Więc teraz możesz powiedzieć:
var list=ToAnonymousList
(
new{A=1, B=2},
new{A=2, B=2}
);
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-06-09 15:58:13
Warto zauważyć, że w końcu istnieje możliwość użycia takiej składni. Został wprowadzony w C # 7.0
var tanks = new List<(Tank AttackingTank, Tank TargetTank)>();
(Tank, Tank) tTank = (new Tank(), new Tank());
tanks.Add(tTank);
var a = tanks[0].AttackingTank;
var b = tanks[0].TargetTank;
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-11-08 13:00:07
A może ExpandoObject ?
dynamic tuple = new ExpandoObject();
tuple.WhatEverYouWantTypeOfTank = new Tank(); // Value of any type
EDITS:
dynamic tuple = new ExpandoObject();
tuple.AttackingTank = new Tank();
tuple.TargetTank = new Tank();
var mylist = new List<dynamic> { tuple };
//access to items
Console.WriteLine(mylist[0].AttackingTank);
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-10-21 10:01:58
Lub jeszcze bardziej proste
var tupleList = (
new[] {
new { fruit = "Tomato", colour = "red"},
new { fruit = "Tomato", colour = "yellow"},
new { fruit = "Apple", colour = "red"},
new { fruit = "Apple", colour = "green"},
new { fruit = "Medlar", colour = "russet"}
}).ToList();
Który traci funkcję statyczną.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-04-20 08:41:56
Żeby dodać jeszcze jeden przydatny kawałek. Czasami używam odpowiedzi Alexa, ale doprowadza mnie to do szaleństwa próbując ją wyśledzić, gdy jej potrzebuję, ponieważ nie jest to oczywiste(znajduję się w poszukiwaniu " new {").
Więc dodałem następującą małą statyczną metodę (chciałbym, żeby była to metoda rozszerzenia, ale jakiego typu?):
public static List<T> CreateEmptyListOf<T>(Func<T> itemCreator)
{
return Enumerable
.Empty<object>()
.Select(o => itemCreator())
.ToList();
}
To izoluje część, która jest inna za każdym razem, gdy potrzebuję tego wzoru od tych, które są takie same. Nazywam to tak:
var emptyList = Ext.CreateEmptyListOf(() => new { Name = default(string), SomeInt = default(int) });
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-06-21 14:45:27
Możesz utworzyć listę obiektów:
List<object> myList = new List<object>();
Następnie dodaj Typ anonimowy do listy:
myList.Add(new {Name = "me", phone = 123});
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-05-17 17:29:50