주조 알고리즘 및 성능 고려 사항을 나열하십시오
-
03-07-2019 - |
문제
다음 코드가 있습니다
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) 시간이 걸리야하므로 차이는 크지 않아야합니다. 그럼에도 불구하고 벤치마킹의 가치가 있습니다 ...