익명 클래스의 일반 목록
C# 3.0에서 다음 구문을 사용하여 익명 클래스를 만들 수 있습니다.
var o = new { Id = 1, Name = "Foo" };
이러한 익명 클래스를 일반 목록에 추가할 수 있는 방법이 있습니까?
예:
var o = new { Id = 1, Name = "Foo" };
var o1 = new { Id = 2, Name = "Bar" };
List<var> list = new List<var>();
list.Add(o);
list.Add(o1);
다른 예:
List<var> list = new List<var>();
while (....)
{
....
list.Add(new {Id = x, Name = y});
....
}
할 수 있는 일:
var list = new[] { o, o1 }.ToList();
이 고양이의 가죽을 벗기는 데는 여러 가지 방법이 있지만 기본적으로 그들은 모두 어딘가에서 유형 추론을 사용할 것입니다. 즉, 일반적인 방법(아마도 확장 방법)을 호출해야 합니다.또 다른 예는 다음과 같습니다.
public static List<T> CreateList<T>(params T[] elements)
{
return new List<T>(elements);
}
var list = CreateList(o, o1);
당신은 이해합니다 :)
여기에 정답이 있다.
string result = String.Empty;
var list = new[]
{
new { Number = 10, Name = "Smith" },
new { Number = 10, Name = "John" }
}.ToList();
foreach (var item in list)
{
result += String.Format("Name={0}, Number={1}\n", item.Name, item.Number);
}
MessageBox.Show(result);
여러 가지 방법이 있지만 여기에 있는 응답 중 일부는 가비지 요소가 포함된 목록을 만들고 있으므로 목록을 지워야 합니다.
일반 유형의 빈 목록을 찾는 경우 튜플 목록에 대해 선택을 사용하여 빈 목록을 만듭니다.요소는 인스턴스화되지 않습니다.
빈 목록을 만드는 한 줄기 방법은 다음과 같습니다.
var emptyList = new List<Tuple<int, string>>()
.Select(t => new { Id = t.Item1, Name = t.Item2 }).ToList();
그런 다음 일반 유형을 사용하여 추가할 수 있습니다.
emptyList.Add(new { Id = 1, Name = "foo" });
emptyList.Add(new { Id = 2, Name = "bar" });
또는 다음과 같은 작업을 수행하여 빈 목록을 만들 수 있습니다(그러나 Tuples의 채우기 컬렉션에도 사용할 수 있으므로 첫 번째 예를 선호합니다).
var emptyList = new List<object>()
.Select(t => new { Id = default(int), Name = default(string) }).ToList();
정확히는 아니지만, 당신은 말할 수 있습니다.List<object>
모든 게 잘 될 겁니다하지만,list[0].Id
작동하지 않습니다.
이것은 C# 4.0의 런타임에서 작동합니다.List<dynamic>
를 얻을 수 것입니다.
C# 7 이상을 사용하는 경우 익명 형식 대신 튜플 형식을 사용할 수 있습니다.
var myList = new List<(int IntProp, string StrProp)>();
myList.Add((IntProp: 123, StrProp: "XYZ"));
그런 것 같다.
List<T> CreateEmptyGenericList<T>(T example) {
return new List<T>();
}
void something() {
var o = new { Id = 1, Name = "foo" };
var emptyListOfAnonymousType = CreateEmptyGenericList(o);
}
효과가 있을 것입니다.
다음과 같이 작성하는 것도 고려해 볼 수 있습니다.
void something() {
var String = string.Emtpy;
var Integer = int.MinValue;
var emptyListOfAnonymousType = CreateEmptyGenericList(new { Id = Integer, Name = String });
}
저는 주로 다음을 사용합니다. 주로 빈 목록으로 "시작"하기 때문입니다.
var list = Enumerable.Range(0, 0).Select(e => new { ID = 1, Name = ""}).ToList();
list.Add(new {ID = 753159, Name = "Lamont Cranston"} );
//etc.
최근에는 이렇게 쓰고 있습니다.
var list = Enumerable.Repeat(new { ID = 1, Name = "" }, 0).ToList();
list.Add(new {ID = 753159, Name = "Lamont Cranston"} );
반복 방법을 사용하면 다음 작업도 수행할 수 있습니다.
var myObj = new { ID = 1, Name = "John" };
var list = Enumerable.Repeat(myObj, 1).ToList();
list.Add(new { ID = 2, Name = "Liana" });
..첫 번째 항목이 이미 추가된 초기 목록을 제공합니다.
코드에서 이 작업을 수행할 수 있습니다.
var list = new[] { new { Id = 1, Name = "Foo" } }.ToList();
list.Add(new { Id = 2, Name = "Bar" });
저는 몇 가지 답변에서 IL을 확인했습니다.이 코드는 효율적으로 빈 목록을 제공합니다.
using System.Linq;
…
var list = new[]{new{Id = default(int), Name = default(string)}}.Skip(1).ToList();
최신 버전 4.0에서는 아래와 같은 동적 기능을 사용할 수 있습니다.
var list = new List<dynamic>();
list.Add(new {
Name = "Damith"
});
foreach(var item in list){
Console.WriteLine(item.Name);
}
}
동적 목록을 만들 수 있습니다.
List<dynamic> anons=new List<dynamic>();
foreach (Model model in models)
{
var anon= new
{
Id = model.Id,
Name=model.Name
};
anons.Add(anon);
}
"dynamic"은 첫 번째 추가된 값으로 초기화됩니다.
다음은 빈 목록으로 시작할 수 있지만 IntelliSense에 액세스할 수 있는 익명 유형 목록을 만드는 또 다른 방법입니다.
var items = "".Select( t => new {Id = 1, Name = "foo"} ).ToList();
첫 번째 항목을 보관하려면 문자열에 한 글자만 넣으십시오.
var items = "1".Select( t => new {Id = 1, Name = "foo"} ).ToList();
여기 제 시도가 있습니다.
List<object> list = new List<object> { new { Id = 10, Name = "Testing1" }, new {Id =2, Name ="Testing2" }};
제가 커스텀 유형의 익명 목록을 만들 때 비슷한 것을 썼을 때 이것을 생각해 냈습니다.
아무도 수집 이니셜라이저를 제안하지 않은 것에 매우 놀랐습니다.이 방법은 목록이 생성될 때만 개체를 추가할 수 있습니다. 따라서 이름을 추가하는 것이 가장 좋은 방법인 것 같습니다.배열을 만든 다음 목록으로 변환할 필요가 없습니다.
var list = new List<dynamic>()
{
new { Id = 1, Name = "Foo" },
new { Id = 2, Name = "Bar" }
};
언제든지 사용할 수 있습니다.object
에 dynamic
하지만 그 때 그것을 진정한 일반적인 방법으로 유지하려고 노력합니다.dynamic
더 말이 되는군요
이 대신:
var o = new { Id = 1, Name = "Foo" };
var o1 = new { Id = 2, Name = "Bar" };
List <var> list = new List<var>();
list.Add(o);
list.Add(o1);
다음과 같이 할 수 있습니다.
var o = new { Id = 1, Name = "Foo" };
var o1 = new { Id = 2, Name = "Bar" };
List<object> list = new List<object>();
list.Add(o);
list.Add(o1);
그러나 다른 범위에서 이와 같은 작업을 수행하려고 하면 컴파일 시간 오류가 발생합니다.
private List<object> GetList()
{
List<object> list = new List<object>();
var o = new { Id = 1, Name = "Foo" };
var o1 = new { Id = 2, Name = "Bar" };
list.Add(o);
list.Add(o1);
return list;
}
private void WriteList()
{
foreach (var item in GetList())
{
Console.WriteLine("Name={0}{1}", item.Name, Environment.NewLine);
}
}
문제는 인텔리센스가 속성 ID와 이름을 표시하지만 런타임에 개체의 멤버만 사용할 수 있다는 것입니다.
.net 4.0에서 해결책은 위의 코드에서 객체 대신 키워드 dynamic is를 사용하는 것입니다.
또 다른 해결책은 반사를 사용하여 속성을 가져오는 것입니다.
using System;
using System.Collections.Generic;
using System.Reflection;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
Program p = new Program();
var anonymous = p.GetList(new[]{
new { Id = 1, Name = "Foo" },
new { Id = 2, Name = "Bar" }
});
p.WriteList(anonymous);
}
private List<T> GetList<T>(params T[] elements)
{
var a = TypeGenerator(elements);
return a;
}
public static List<T> TypeGenerator<T>(T[] at)
{
return new List<T>(at);
}
private void WriteList<T>(List<T> elements)
{
PropertyInfo[] pi = typeof(T).GetProperties();
foreach (var el in elements)
{
foreach (var p in pi)
{
Console.WriteLine("{0}", p.GetValue(el, null));
}
}
Console.ReadLine();
}
}
}
다음과 같은 방법으로 수행할 수 있습니다.
var o = new { Id = 1, Name = "Foo" };
var o1 = new { Id = 2, Name = "Bar" };
var array = new[] { o, o1 };
var list = array.ToList();
list.Add(new { Id = 3, Name = "Yeah" });
제가 보기에는 약간 "해킹"한 것처럼 보이지만, 정말로 목록이 필요하고 익명 배열을 사용할 수 없다면 효과가 있습니다.
이것은 오래된 질문이지만, 저는 제 6번 답을 넣어야겠다고 생각했습니다.나는 종종 코드에 쉽게 입력되는 테스트 데이터를 튜플 목록으로 설정해야 합니다.몇 가지 확장 기능을 사용하면 각 항목에서 이름을 반복하지 않고 이처럼 멋지고 간단한 형식을 사용할 수 있습니다.
var people= new List<Tuple<int, int, string>>() {
{1, 11, "Adam"},
{2, 22, "Bill"},
{3, 33, "Carol"}
}.Select(t => new { Id = t.Item1, Age = t.Item2, Name = t.Item3 });
그러면 IE 번호가 표시됩니다. 목록을 추가하려면 ToList()를 추가하십시오.
이 마법은 https://stackoverflow.com/a/27455822/4536527 에서 설명한 것처럼 튜플에 대한 사용자 지정 확장 Add 메서드에서 비롯됩니다.
public static class TupleListExtensions {
public static void Add<T1, T2>(this IList<Tuple<T1, T2>> list,
T1 item1, T2 item2) {
list.Add(Tuple.Create(item1, item2));
}
public static void Add<T1, T2, T3>(this IList<Tuple<T1, T2, T3>> list,
T1 item1, T2 item2, T3 item3) {
list.Add(Tuple.Create(item1, item2, item3));
}
// and so on...
}
제가 유일하게 좋아하지 않는 것은 이름과 유형이 분리되어 있다는 것입니다. 하지만 만약 여러분이 정말로 새로운 수업을 만들고 싶지 않다면, 이 접근법은 여러분이 읽을 수 있는 데이터를 가질 수 있게 해줄 것입니다.
var list = new[]{
new{
FirstField = default(string),
SecondField = default(int),
ThirdField = default(double)
}
}.ToList();
list.RemoveAt(0);
▁a▁you를 초기화해야 하는 경우입니다.List<T>
한 가지 아이디어는 익명의 목록을 만든 다음 삭제하는 것입니다.
var list = new[] { o, o1 }.ToList();
list.Clear();
//and you can keep adding.
while (....)
{
....
list.Add(new { Id = x, Name = y });
....
}
또는 확장 방법으로 더 쉬울 것입니다.
public static List<T> GetEmptyListOfThisType<T>(this T item)
{
return new List<T>();
}
//so you can call:
var list = new { Id = 0, Name = "" }.GetEmptyListOfThisType();
어쩌면 더 짧을지도 모르지만,
var list = new int[0].Select(x => new { Id = 0, Name = "" }).Tolist();
이 대답에서 파생하여, 저는 작업을 수행할 수 있는 두 가지 방법을 생각해냈습니다.
/// <summary>
/// Create a list of the given anonymous class. <paramref name="definition"/> isn't called, it is only used
/// for the needed type inference. This overload is for when you don't have an instance of the anon class
/// and don't want to make one to make the list.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="definition"></param>
/// <returns></returns>
#pragma warning disable RECS0154 // Parameter is never used
public static List<T> CreateListOfAnonType<T>(Func<T> definition)
#pragma warning restore RECS0154 // Parameter is never used
{
return new List<T>();
}
/// <summary>
/// Create a list of the given anonymous class. <paramref name="definition"/> isn't added to the list, it is
/// only used for the needed type inference. This overload is for when you do have an instance of the anon
/// class and don't want the compiler to waste time making a temp class to define the type.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="definition"></param>
/// <returns></returns>
#pragma warning disable RECS0154 // Parameter is never used
public static List<T> CreateListOfAnonType<T>(T definition)
#pragma warning restore RECS0154 // Parameter is never used
{
return new List<T>();
}
다음과 같은 방법을 사용할 수 있습니다.
var emptyList = CreateListOfAnonType(()=>new { Id = default(int), Name = default(string) });
//or
var existingAnonInstance = new { Id = 59, Name = "Joe" };
var otherEmptyList = CreateListOfAnonType(existingAnonInstance);
이 답은 비슷한 생각을 가지고 있지만, 저는 그 방법들을 만든 후에야 그것을 보았습니다.
반사 사용
이 항목에 대한 Microsoft 설명서입니다.
using System;
using System.Collections;
using System.Collections.Generic;
var anonObj = new { Id = 1, Name = "Foo" };
var anonType = anonObj.GetType();
var listType = typeof(List<>);
// We know that List<> have only one generic argument, so we do this:
var contructed = listType.MakeGenericType(anonType);
// Create instance
var instance = Activator.CreateInstance(contructed);
// Using it
var list = (IList)instance;
list.Add(anonObj);
위해서Dictionary<,>
당신은 두 개의 인수를 통과해야 합니다.
예: dicType.MakeGenericType( type1, type2 )
제약 조건이 있는 일반 유형의 경우(where T : struct
), 우리는 더 많은 검증을 해야 합니다.자세한 내용은 Microsoft 문서를 참조하십시오.
사용해 보십시오.
var result = new List<object>();
foreach (var test in model.ToList()) {
result.Add(new {Id = test.IdSoc,Nom = test.Nom});
}
언급URL : https://stackoverflow.com/questions/612689/a-generic-list-of-anonymous-class
'source' 카테고리의 다른 글
Git: Git을 사용할 때 권한 거부(공개 키) 오류를 해결하는 방법은 무엇입니까? (0) | 2023.05.14 |
---|---|
pythonw.exe 또는 python.exe? (0) | 2023.05.14 |
Xcode 프로젝트 및 관련 폴더 복제 및 이름 바꾸기 (0) | 2023.05.14 |
jQuery.on 및 hover를 사용할 수 있습니까? (0) | 2023.05.14 |
원격으로 Maria에 연결할 수 없음DB (0) | 2023.05.14 |