2012-03-10 8 views
2

"마리오"비디오 게임을 만들려고합니다. 교차하는 물체를 얻기 위해 선생님이 예제 데모를 제공해주었습니다.이 데모를 통해 물체가 정확히 하나의 다른 물체에 닿아 있는지 감지 할 수 있고 첫 번째 물체 메소드가 찾은 결과가 리턴됩니다. 현재 객체가 현재 접촉하고있는 모든 객체의 배열을 반환하는 대신에 노력하고 있습니다. 나는 그것을 만져 현재 모든 객체의 배열을 반환 할 수 있었지만되고 있음을 지금과 같은특정 클래스가 포함 된 배열은 어떻게 요청합니까?

if (array.Contains(Mario)) 
    { 
    //Do Work here 
    } 

배열, 배열이 필요한 형식의 개체가 포함되어 있는지 확인하는 쉬운/효율적인 방법이 필요합니다 그것이 포함되어 있는지 (Mario), 교차 Sprite의 반환 된 배열이지만 실제로 Mario 유형의 객체가 포함되어 있는지 물어 보면 "Error 14 'WindowsGame10.Mario'는 'type'이지만 '변수' ". 나는 for 루프로이 작업을 수행 할 수 있으며 배열 if (array[i].GetType() == typeof(Mario)) 내의 각 개별 색인을 요청할 수 있지만 코드 내에서이 검사를 수행하고 동일한 코드를 반복해서 다시 입력해야하는 시간은 느낀다. 이것을 수행하는보다 효율적인 방법을 배워야합니다. 저는 컴퓨터 프로그래밍의 첫 해에 C# XNA로 작업하고 있으며 이해할 수있는 솔루션이 필요합니다. 이 작업을 수행하는 더 좋은 방법이 있다면 알려주십시오.

+1

당신은 항상 다만 방법이 루프를 포장 수 :

static public bool ContainsType(this Array array, Type type) { int len = array.Length; // Note that putting this in the loop is slightly slower // because the compiler can't assume that a property value // remains constant. for (int i = 0; i < len; i++) { if (array.GetValue(i).GetType() == type) return true; } return false; } 

과 같이 사용됩니다 : 그냥 다른 접근 방식을 제공하기 위해이 같은 확장 방법을 정의 할 수 있습니다 . – prelic

답변

6

당신은 LINQ의 OfType()Any() 방법을 사용할 수 있습니다 Linq를 사용

if (array.OfType<Mario>().Any()) 
{ 
+0

감사. 그건 내가 사용하는 위험에 처한 for 루프의 양을 크게 줄였다. –

+3

첫 번째 일치 항목을 찾거나 일치 항목이 없을 경우 전체 배열을 탐색 할 때까지 배열을 계속 탐색합니다. Linq는 프로그래밍 작업을 줄여주는 훌륭한 추상화이지만 루프를 직접 코딩하는 것보다 실제로 약간 더 느릴 수 있습니다.많은 수의 게임 개체 (수천 또는 그 이상)가있는 경우 O (n) 검색보다 나은 저장소 구조를 최적화해야합니다. –

+0

@EricJ. 예. 그러나 저장 메커니즘을 변경하지 않고도이 솔루션을 반복하면 많은 도움이되지 않습니다. 사전으로 변경하거나 유형별로 별도의 콜렉션을 변경하는 것은 이것이 언제 어떻게 사용 될지에 따라 최적화 될 수 있습니다. –

4

당신이 할 수 있습니다

var marios = array.OfType<Mario>(); 
if (marios.Any()) 
{ 
    //Stuff 
} 
1

대부분 정직 방법 (LINQ를 사용하지 않고) is 키워드를 사용하는 것입니다 :

foreach (Object obj in array) 
{ 
    if (obj is Mario) 
    { 
     ... 
    } 
} 

업데이트 : 당신이 정확한 Type 일치해야하고, 코드 중복을 피하려면,이 유사한 오히려 단순한 확장 방법이 가장 좋은 것입니다 생각 -

public static bool ContainsType<T>(this T[] arr, Type type) 
{ 
    for (int i = 0; i < arr.Length; i++) 
     if (arr[i].GetType().Equals(type)) 
      return true; 
    return false; 
} 

그리고 사용 -

if (array.ContainsType(typeof(Mario))) 
+0

내가 이해할 수있는 것은 (여기에서 벗어날 수 있음) 키워드는 부모님의 반성과 관련이 있으며, 미래에 마리오의 대리인을 만들면이 클래스와 상호 작용할 수 없기를 원할 것입니다. "그들"은 반성과 함께 작동하기 때문에 마리오베이스 클래스를 상속 받기 때문에 그들과 상호 작용합니다. –

+0

@MatthewCrandall : is-operator [Reflection을 사용하지 않고 매우 효율적입니다] (http://stackoverflow.com/a/1134104/284240). –

+0

@MatthewCrandall 그렇습니다. 상속받은 타입도 포함되어 있습니다.하지만 원치 않는 결과라는 점은 분명하지 않습니다. 어쨌든, 내 게시물을 업데이 트했습니다. 또한 나는 당신이 상속을 반성으로 잘못 언급하고 있다고 생각합니다. – Acidic

2

그냥 다음이가 iteratio 벗어나됩니다

if(array.Any(a=>a is Mario)) 
{ 
} 

어떤 마리오가 있는지 알 필요가 있다면 n 즉시 첫 번째 일치를 찾습니다.

+0

FYI - 내 솔루션은 전체 배열을 반복적으로 (필연적으로) 반복하지 않지만 Any() 호출로 인해 첫 번째가 발견되자 마자 나간다. –

+0

흠, 그 사실을 알지 못했습니다. 감사 리드. – labroo

+1

LINQ의 지연된 실행 모델 때문입니다. –

1

Linq 답변은 훌륭합니다. 코드 중복을 피하고,

Array a = new object[] { "The meaning of life.", 42 }; 
    bool hasString = a.ContainsType(typeof(string)); // true 
    bool hasInteger = a.ContainsType(typeof(int)); // true 
    bool hasChar = a.ContainsType(typeof(char)); // false 
관련 문제