문제

다음 코드가 있습니다

class Program
    {
        static void Main(string[] args)
        {
            List<A> aList = new List<A>();

            var aObj = new A();

            aObj.Go(aList.Cast<IB>());
        }
    }

    class A : IB
    {
        public void Go(IEnumerable<IB> interfaceList)
        {
            foreach (IB ibby in interfaceList)
            {
                Console.WriteLine("Here");
            }
        }
    }

    interface IB
    {
        void Go(IEnumerable<IB> interfaceList);
    }

}

나는 원래 목록을 전달하려고 시도했지만 그것은 그 목록을 통과시켰다 작동하지 않습니다. 많은 도움을받은 후 그래서 나는 ienumerable을 통과하는 것이 .oftype (ib)를 가로 질러 물체를 얻는 유일한 방법이라는 것을 알았습니다.

불행히도 내 코드에서 다음 줄은 수천 번 실행됩니다.

aList.Cast<IB>();

나는 그것이 알고리즘 적으로 (IL에서) 알고리즘 적으로 구현 된 방법과 시간 순서가 무엇인지 알고 있는지 궁금했습니다.

즉, 각 항목을 캐스팅하는 Foreach 루프보다 빠르나요, 아니면 정확히 그것이하는 일입니까?

편집하다 메인 클래스는 실제 객체 목록을 유지해야합니다. 그러나 독자는 인터페이스를 통해서만 접촉 할 수 있습니다.

도움이 되었습니까?

해결책

당신은 변경해야합니다 Go 에게:

public void Go<T>(IEnumerable<T> interfaceList)
    where T : IB
{
    foreach (IB ibby in interfaceList)
    {
        Console.WriteLine("Here");
    }
}

그런 다음 전화 할 필요없이 괜찮을 것입니다 Cast. 캐스트의 소스 코드 구현은 3.5와 3.5SP1로 변경되었다고 생각하지만 캐스트의 소스 코드 구현은 매우 간단하다고 생각합니다. 그러나 일반 반복자 블록 방식으로 새로운 상태 기계 등을 설정해야 할 것입니다. 가능하면 피하는 것이 좋습니다.

새로운 방법은 일반적이지만, 유형 추론은 일반적으로 그것을 관리해야하므로 지정할 필요가 없습니다. T 명시 적으로.

다른 팁

왜 목록을 다음과 같은 선언하지 않겠습니까?

List<IB> aList = new List<IB>();

특히 콘크리트 클래스 목록이 있어야하는 것이 있습니까?


따라서이 경우 도메인의 목록 부분을 만들었습니다. iibcollection과 같은 인터페이스를 가지고 (예 :) 독자가 액세스 할 수 있도록 메소드를 노출시킵니다. 예를 들어:

interface IIBCollection{
    IEnumerable<IB> IBs { get; }
}

// and in your implementation you can do

IEnumerable<IB> IBs { 
    get { 
        foreach(IB ib in innerList) yield return ib; 
}}

내부적으로 각 항목을 캐스팅하는 foreach보다 약간 느린 Castiterator로 구현됩니다.

캐스트 방법은 목록을 통해 루프하고 각 항목을 캐스팅합니다.

목록을 수천 번 사용하려는 경우 캐스팅 결과를 목록으로 저장하십시오.

그것이 불가능한 경우 (즉, 매번 목록을 변경) List<IB> 대신 a List<A>.

이것이 C#의 공분산이 무엇인지 아닌가? 나는 당신이 무엇을하려고하는지 알지 못하므로 왜 그것이 수천 번의 퇴장인지에 대해서는 언급 할 수 없습니다.

두 가지 방법 (캐스트 확장 방법 및 캐스트가있는 루프)을 벤치마킹하는 것은 상당히 단순한 문제입니다. 그러나 캐스트가 열거 가능한 클래스의 확장 방법이며 일반적으로 ienumerables를 다루는 것을 감안할 때 이것이 정확히 구현이라고 생각합니다. 가장 큰 속도를 원한다면 목록에서 특별히 작동하는 자체 확장 방법 (인덱스별로 각 요소를 가져옵니다)을 구현하는 것이 가장 좋습니다. 그럼에도 불구하고 두 방법 모두 O (n) 시간이 걸리야하므로 차이는 크지 않아야합니다. 그럼에도 불구하고 벤치마킹의 가치가 있습니다 ...

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top