2017-12-30 65 views
3

나는 Unity로 RTS 게임을 만들고 있습니다. 내 게임에는 트리, 팜과 같은 다양한 유형의 리소스가 있습니다. 각 리소스는 GameObject이며이를 제어하는 ​​메인 스크립트를 소유하고 있습니다.일반 메서드 호출은 다른 일반 메서드 내에서 허용됩니까?

Ex. 나는 나무를 수확하고 싶다. 나는 이것을 부른다.

gameObject.GetComponent<Tree>().Harvest(); 

팜을 수확하려면 동일한 스크립트를 호출하지만 "트리"를 "팜"으로 변경하면되지만 "코드"는 복제됩니다. 그래서 저는 이것을 generics method를 사용하여 추상화합니다.

void Harvest<T>(){ 
    gameObject.GetComponent<T>().Harvest(); 
} 

하지만 C# 컴파일러는 그렇게 할 수 없습니다. 제네릭 메소드를 내부에서 사용하는 제네릭 메소드를 정의하는 것이 가능한지 알고 싶습니다. 그렇지 않다면 이런 식으로 내 코드를 추상화 할 수있는 방법이 있습니까? 고맙습니다.

오류 메시지 :

'T'는 '수확'에 대한 정의없이 확장 메서드 '수확'유형 'T'의 첫 번째 인수를 받아들이는 포함되어 있지 않습니다를 볼 수 있습니다 (당신은 사용하여 누락 지시문 또는 어셈블리 참조?) 어셈블리 CSHARP]

+0

"저를 그렇게시키지 않을 것입니다"라고 말하면 확실하지 않습니다. * 특정 * ... 오류 메시지? 예를 들어'GetComponent'에 제약이 있습니까? –

+3

또한 ** 모든 ** 유형에는'.Harvest' 메소드가 있습니까? 확장 방법입니까? 그렇지 않으면'void Harvest ()와 같은 'Harvest' 메소드를 제공하는 인터페이스를 구현하는 T를 허용하는 것과 같이 제약 조건을 직접 추가해야합니다. T : IHarvestable {...' –

+0

오류 메시지 덧붙였다. @ LasseVågsætherKarlsen. –

답변

5

문제에 ...

void Harvest<T>(){ 
    gameObject.GetComponent<T>().Harvest(); 
} 

작업 ... C# 컴파일러 어느 concr 알고 없다는 것이다 ete 유형 T됩니다. 따라서 메소드 Harvest을 사용할 수 있다는 것을 알 수 없으며 정확한 선언을 알지도 못합니다 ( void 또는 bool 또는 그 외의 옵션을 반환합니까?). C#은 강력한 형식의 언어이므로 컴파일 타임에이를 알고 있어야합니다. 이것은 런타임에 모든 것이 잘 돌아갈 것이라는 확실성을 제공합니다.

해결 방법은 제네릭 형식 제약 조건을 지정하여 컴파일러에게 힌트를 제공하는 것입니다. 이렇게하려면 인터페이스를 선언하고 Harvest 메서드를 사용하는 구성 요소로 인터페이스를 구현해야합니다.

public interface IHarvestable 
{ 
    void Harvest(); 
} 

하기에 제약 조건을 지정

void Harvest<T>() where T : IHarvestable 
{ 
    gameObject.GetComponent<T>().Harvest(); 
} 
당신이 기본 클래스의 컨트롤에있는 다른 상황에서

, 당신은 또한 (아마도으로 추상 기본 클래스에서 필요한 방법을 선언 할 수 있습니다) 대신 인터페이스 대신 generic type constraint에 기본 클래스를 지정하십시오.

+0

나는 뭔가를 배웠다. 고맙습니다. –

2

Harvest()를 사용하는 모든 객체에 대한 인터페이스를 정의하고 T는 그 인터페이스를 확장하는 정의의 C#이 지원하기 때문에 바로 대답에 "해키"또한 언급

public interface IHarvestable 
{ 
    void Harvest(); 
} 

// In your class: 
void Harvest<T>() where T: IHarvestable 
{ 
    gameObject.GetComponent<T>().Harvest(); 
} 

BAD 대안을 (- 않습니다 NOT) 연습에서 사용 : 당신은 당신이 dynamic 사용할 수있는 체크 -time 건너 뛰려면이 런타임에 해결 메서드 호출로 이어지는, 나쁜 관행입니다

dynamic harvestable = gameObject.GetComponent<T>(); 
harvestable.Harvest(); 

주, 성능 단점으로 이어지는 등 코드를 만들기 더 많은 발생하기 쉬운 오류.예를 들어 Harvest()을 구현하지 않는 T 유형 인스턴스의 메서드 사용은 컴파일러에서 허용되어 런타임 오류가 발생할 수 있습니다.

+0

동적 방법을 사용하면 흥미로운 것처럼 보입니다. 예제를 보여줄 수 있습니까? –

+4

인터페이스 방식을 사용하는 것이 좋습니다. –