List <T>에서 특정 요소를 어떻게 찾을 수 있습니까?


114

내 응용 프로그램은 다음과 같은 목록을 사용합니다.

List<MyClass> list = new List<MyClass>();

Add메서드를 사용하면의 다른 인스턴스 MyClass가 목록에 추가됩니다.

MyClass 특히 다음과 같은 방법을 제공합니다.

public void SetId(String Id);
public String GetId();

메서드 MyClass를 사용하여의 특정 인스턴스를 어떻게 찾을 수 GetId있습니까? 나는 Find방법 이 있다는 것을 알고 있지만 이것이 여기에서 작동하는지 모르겠다?!

답변:


263

람다 식 사용

MyClass result = list.Find(x => x.GetId() == "xy");

참고 : C #에는 속성에 대한 기본 제공 구문이 있습니다. getter 및 setter 메소드를 작성하는 대신 (Java에서 익숙한 것처럼) 다음과 같이 작성하십시오.

private string _id;
public string Id
{
    get
    {
        return _id;
    }
    set
    {
        _id = value;
    }
}

valueset 접근 자에서만 알려진 문맥 키워드입니다. 속성에 할당 된 값을 나타냅니다.

이 패턴이 자주 사용되기 때문에 C #은 자동 구현 속성을 제공 합니다 . 위 코드의 짧은 버전입니다. 그러나 지원 변수는 숨겨져 있고 액세스 할 수 없습니다 (그러나 VB의 클래스 내에서 액세스 할 수 있음).

public string Id { get; set; }

필드에 액세스하는 것처럼 간단히 속성을 사용할 수 있습니다.

var obj = new MyClass();
obj.Id = "xy";       // Calls the setter with "xy" assigned to the value parameter.
string id = obj.Id;  // Calls the getter.

속성을 사용하여 다음과 같은 목록에서 항목을 검색합니다.

MyClass result = list.Find(x => x.Id == "xy"); 

읽기 전용 속성이 필요한 경우 자동 구현 속성을 사용할 수도 있습니다.

public string Id { get; private set; }

이렇게하면 Id클래스 내에서 설정할 수 있지만 외부에서는 설정할 수 없습니다. 파생 클래스에서도 설정해야하는 경우 setter를 보호 할 수도 있습니다.

public string Id { get; protected set; }

마지막으로 속성을 다음 virtual과 같이 선언 하고 파생 클래스에서 재정 의하여 getter 및 setter에 대해 다른 구현을 제공 할 수 있습니다. 일반적인 가상 방법과 마찬가지로.


C # 6.0 (Visual Studio 2015, Roslyn)부터는 인라인 이니셜 라이저로 getter 전용 자동 속성을 작성할 수 있습니다.

public string Id { get; } = "A07"; // Evaluated once when object is initialized.

대신 생성자 내에서 getter 전용 속성을 초기화 할 수도 있습니다. Getter 전용 자동 속성은 개인 setter가있는 자동 구현 속성과 달리 진정한 읽기 전용 속성입니다.

이것은 읽기-쓰기 자동 속성에서도 작동합니다.

public string Id { get; set; } = "A07";

C # 6.0부터는 속성을 식 본문 멤버로 작성할 수도 있습니다.

public DateTime Yesterday => DateTime.Date.AddDays(-1); // Evaluated at each call.
// Instead of
public DateTime Yesterday { get { return DateTime.Date.AddDays(-1); } }

참조 : .NET 컴파일러 플랫폼 ( "Roslyn")
         C # 6의 새로운 언어 기능

C # 7.0 부터는 getter와 setter 모두 표현식 본문으로 작성할 수 있습니다.

public string Name
{
    get => _name;                                // getter
    set => _name = value;                        // setter
}

이 경우 setter는 식이어야합니다. 진술이 될 수 없습니다. 위의 예는 C #에서 할당을 식이나 문으로 사용할 수 있기 때문에 작동합니다. 할당 식의 값은 할당 자체가 부작용 인 할당 된 값입니다. 이것은 당신이 한 번에 두 개 이상의 변수에 값을 할당 할 수 있습니다 : x = y = z = 0에 해당 x = (y = (z = 0))하고 진술하는 것과 같은 효과가 있습니다 x = 0; y = 0; z = 0;.

2020 년 11 월에 출시 될 예정인 다음 언어 버전 인 C # 9.0은 개체 이니셜 라이저에서 초기화 할 수있는 읽기 전용 (또는 더 나은 한 번만 초기화) 속성을 허용합니다. 이것은 현재 getter 전용 속성으로는 불가능합니다.

public string Name { get; init; }

var c = new C { Name = "c-sharp" };

2
감사합니다. db 작업의 경우 다음과 같이 표시 IQueryable<T> result = db.Set<T>().Find(//just id here//).ToList();됩니다. 기본 키를 찾고 있다는 것을 이미 알고있을 것입니다. 정보를 위해.
씨 금발

나는 이것이 오래된 대답이라는 것을 알고 있지만 비교 중에 실수로 값이 설정되지 않도록 get과 set를 다른 방법으로 분리했습니다.
Joel Trauger

@JoelTrauger : 비교는 속성을 읽고 따라서 getter 만 호출합니다.
Olivier Jacot-Descombes

이것은 사실이지만 우발적 인 할당은 setter를 호출하고 속성을 수정합니다. 참조 return object.property = valuereturn object.property == value
Joel Trauger

별도의 set 메서드를 실수로 호출하면 속성도 수정됩니다. 별도의 get set 메서드가 어떻게 안전성을 향상시킬 수 있는지 모르겠습니다.
Olivier Jacot-Descombes

19
var list = new List<MyClass>();
var item = list.Find( x => x.GetId() == "TARGET_ID" );

또는 하나만 있고 당신이 원하는 것이 SingleOrDefault될 수 있도록 강제하고 싶다면

var item = list.SingleOrDefault( x => x.GetId() == "TARGET" );

if ( item == null )
    throw new Exception();

예외를 던지고 싶다면 왜 singleOrDefault를 사용합니까, Use Single ()
코드 이름 Jack


6

또는 LINQ 를 사용하지 않으려는 경우 구식 방식으로 수행 할 수 있습니다.

List<MyClass> list = new List<MyClass>();
foreach (MyClass element in list)
{
    if (element.GetId() == "heres_where_you_put_what_you_are_looking_for")
    {

        break; // If you only want to find the first instance a break here would be best for your application
    }
}

4

LINQ 확장을 사용할 수도 있습니다 .

string id = "hello";
MyClass result = list.Where(m => m.GetId() == id).First();

4
또는 First의 다른 과부하 :MyClass result = list.First(m => m.GetId() == id);
Marcel Gosselin 2012 년

3

익명 메서드 구문을 사용하여 작성된 술어를 사용하면 문제를 가장 간결하게 해결할 수 있습니다.

MyClass found = list.Find(item => item.GetID() == ID);

0
public List<DealsCategory> DealCategory { get; set; }
int categoryid = Convert.ToInt16(dealsModel.DealCategory.Select(x => x.Id));

이 코드가 질문에 답할 수 있지만 문제를 해결하는 방법을 설명하고 코드를 예제 또는 참조로 제공하는 것이 좋습니다. 코드 전용 답변은 혼란스럽고 컨텍스트가 부족할 수 있습니다.
Robert Columbia

0

검색 기준을 유지하는 검색 변수를 만들 수 있습니다. 다음은 데이터베이스를 사용한 예입니다.

 var query = from o in this.mJDBDataset.Products 
             where o.ProductStatus == textBox1.Text || o.Karrot == textBox1.Text 
             || o.ProductDetails == textBox1.Text || o.DepositDate == textBox1.Text 
             || o.SellDate == textBox1.Text
             select o;

 dataGridView1.DataSource = query.ToList();

 //Search and Calculate
 search = textBox1.Text;
 cnn.Open();
 string query1 = string.Format("select * from Products where ProductStatus='"
               + search +"'");
 SqlDataAdapter da = new SqlDataAdapter(query1, cnn);
 DataSet ds = new DataSet();
 da.Fill(ds, "Products");
 SqlDataReader reader;
 reader = new SqlCommand(query1, cnn).ExecuteReader();

 List<double> DuePayment = new List<double>();

 if (reader.HasRows)
 {

  while (reader.Read())
  {

   foreach (DataRow row in ds.Tables["Products"].Rows)
   {

     DuePaymentstring.Add(row["DuePayment"].ToString());
     DuePayment = DuePaymentstring.Select(x => double.Parse(x)).ToList();

   }
  }

  tdp = 0;
  tdp = DuePayment.Sum();                        
  DuePaymentstring.Remove(Convert.ToString(DuePaymentstring.Count));
  DuePayment.Clear();
 }
 cnn.Close();
 label3.Text = Convert.ToString(tdp + " Due Payment Count: " + 
 DuePayment.Count + " Due Payment string Count: " + DuePaymentstring.Count);
 tdp = 0;
 //DuePaymentstring.RemoveRange(0,DuePaymentstring.Count);
 //DuePayment.RemoveRange(0, DuePayment.Count);
 //Search and Calculate

여기서 "var query"는 검색 변수를 통해 제공하는 검색 기준을 생성합니다. 그런 다음 "DuePaymentstring.Select"는 주어진 기준과 일치하는 데이터를 선택합니다. 이해하는 데 문제가 있으면 언제든지 물어보십시오.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.