Programming

IList 사용시기 및 List 사용시기

procodes 2020. 5. 24. 20:43
반응형

IList 사용시기 및 List 사용시기


나는 IList가 인터페이스이고 List가 구체적인 유형이라는 것을 알고 있지만 여전히 각 유형을 언제 사용 해야할지 모르겠습니다. 내가 지금하고있는 일은 인터페이스를 사용하는 Sort 또는 FindAll 메소드가 필요하지 않은 것입니다. 내가 맞아? 인터페이스 또는 콘크리트 유형을 언제 사용할지 결정하는 더 좋은 방법이 있습니까?


내가 따르는 두 가지 규칙이 있습니다.

  • 작동하는 가장 기본적인 유형을 수락하십시오
  • 사용자에게 필요한 가장 풍부한 유형을 반환

따라서 컬렉션을 취하는 함수 나 메서드를 작성할 때는 List가 아니라 IList <T>, ICollection <T> 또는 IEnumerable <T>를 사용하도록 작성하십시오. System.Object도 T 일 수 있기 때문에 이종 목록에도 일반 인터페이스가 작동합니다. 이렇게하면 스택이나 다른 데이터 구조를 사용하기로 결정한 경우 골치 아프게됩니다. 함수에서해야 할 모든 것이 foreach이면 IEnumerable <T> 만 있으면됩니다.

반면, 함수에서 객체를 반환 할 때는 사용자가 캐스트하지 않고도 가장 풍부한 작업 집합을 사용자에게 제공하려고합니다. 이 경우 내부적으로 List <T>이면 복사본을 List <T>로 반환하십시오.


FxCop에서 확인한 Microsoft 지침은 공용 API에서 List <T> 사용을 권장하지 않습니다. IList <T>를 선호하십시오.

또한 이제는 거의 항상 1 차원 배열을 IList <T>로 선언하므로 Array.Length 대신 IList <T> .Count 속성을 일관되게 사용할 수 있습니다. 예를 들면 다음과 같습니다.

public interface IMyApi
{
    IList<int> GetReadOnlyValues();
}

public class MyApiImplementation : IMyApi
{
    public IList<int> GetReadOnlyValues()
    {
        List<int> myList = new List<int>();
        ... populate list
        return myList.AsReadOnly();
    }
}
public class MyMockApiImplementationForUnitTests : IMyApi
{
    public IList<int> GetReadOnlyValues()
    {
        IList<int> testValues = new int[] { 1, 2, 3 };
        return testValues;
    }
}

사람들이 항상 간과하는 중요한 것이 있습니다.

일반 배열을 IList<T>매개 변수 를 허용하는 것으로 전달한 다음 호출 IList.Add()하여 런타임 예외를 수신 할 수 있습니다 .

Unhandled Exception: System.NotSupportedException: Collection was of a fixed size.

예를 들어 다음 코드를 고려하십시오.

private void test(IList<int> list)
{
    list.Add(1);
}

다음과 같이 호출하면 런타임 예외가 발생합니다.

int[] array = new int[0];
test(array);

이는 일반 배열을 사용 IList<T>하여 Liskov 대체 원칙 위반 하기 때문에 발생합니다 .

이러한 이유로 전화 IList<T>.Add()거는 경우 List<T>대신을 (를) 요구하는 것이 좋습니다 IList<T>.


나는 매개 변수를 취했지만 반환하지 않는 Lee의 조언에 동의합니다.

인터페이스를 반환하도록 메서드를 지정하면 소비하는 메서드를 모르더라도 나중에 정확한 구현을 자유롭게 변경할 수 있습니다. List <T>에서 변경할 필요는 없지만 나중에 추가 기능을 위해 사용자 지정 목록 라이브러리를 사용하도록 변경해야한다고 생각했습니다. IList <T> 만 반환했기 때문에 라이브러리를 사용하는 사람들은 코드를 변경하지 않아도됩니다.

Of course that only need apply to methods that are externally visible (i.e. public methods). I personally use interfaces even in internal code, but as you are able to change all the code yourself if you make breaking changes it's not strictly necessary.


IEnumerable you should try and use the least specific type that suits your purpose. IEnumerable is less specific than IList You use IEnumerable when you want to loop through the items in a collection

IList IList implements IEnumerable You should use IList when you need access by index to your collection, add and delete elements, etc..

List List implements IList


It's always best to use the lowest base type possible. This gives the implementer of your interface, or consumer of your method, the opportunity to use whatever they like behind the scenes.

For collections you should aim to use IEnumerable where possible. This gives the most flexibility but is not always suited.


If you're working within a single method (or even in a single class or assembly in some cases) and no one outside is going to see what you're doing, use the fullness of a List. But if you're interacting with outside code, like when you're returning a list from a method, then you only want to declare the interface without necessarily tying yourself to a specific implementation, especially if you have no control over who compiles against your code afterward. If you started with a concrete type and you decided to change to another one, even if it uses the same interface, you're going to break someone else's code unless you started off with an interface or abstract base type.


I don't think there are hard and fast rules for this type of thing, but I usually go by the guideline of using the lightest possible way until absolutely necessary.

For example, let's say you have a Person class and a Group class. A Group instance has many people, so a List here would make sense. When I declare the list object in Group I will use an IList<Person> and instantiate it as a List.

public class Group {
  private IList<Person> people;

  public Group() {
    this.people = new List<Person>();
  }
}

And, if you don't even need everything in IList you can always use IEnumerable too. With modern compilers and processors, I don't think there is really any speed difference, so this is more just a matter of style.


You are most often better of using the most general usable type, in this case the IList or even better the IEnumerable interface, so that you can switch the implementation conveniently at a later time.

However, in .NET 2.0, there is an annoying thing - IList does not have a Sort() method. You can use a supplied adapter instead:

ArrayList.Adapter(list).Sort()

You should use the interface only if you need it, e.g., if your list is casted to an IList implementation other than List. This is true when, for example, you use NHibernate, which casts ILists into an NHibernate bag object when retrieving data.

If List is the only implementation that you will ever use for a certain collection, feel free to declare it as a concrete List implementation.


In situations I usually come across, I rarely use IList directly.

Usually I just use it as an argument to a method

void ProcessArrayData(IList almostAnyTypeOfArray)
{
    // Do some stuff with the IList array
}

This will allow me to do generic processing on almost any array in the .NET framework, unless it uses IEnumerable and not IList, which happens sometimes.

It really comes down to the kind of functionality you need. I'd suggest using the List class in most cases. IList is best for when you need to make a custom array that could have some very specific rules that you'd like to encapsulate within a collection so you don't repeat yourself, but still want .NET to recognize it as a list.


AList object allows you to create a list, add things to it, remove it, update it, index into it and etc. List is used whenever you just want a generic List where you specify object type in it and that's it.

IList on the other hand is an Interface. Basically, if you want to create your own type of List, say a list class called BookList, then you can use the Interface to give you basic methods and structure to your new class. IList is for when you want to create your own, special sub-class that implements List.

Another difference is: IList is an Interface and cannot be instantiated. List is a class and can be instantiated. It means:

IList<string> MyList = new IList<string>();

List<string> MyList = new List<string>

참고URL : https://stackoverflow.com/questions/17170/when-to-use-ilist-and-when-to-use-list

반응형