>

ReSharper는 "손상 가능한"if 블록에 대해서는 null 전파를 사용하도록 제안하지만 "forceVelocityCalculator"에 대해서는 제안이 없습니다.

void Damage(Collider hitCollider)
{
    IDamageable damageable = hitCollider.GetComponent<IDamageable>();
    if (damageable != null)
    {
        damageable.TakeDamage(_damage);
    }
}
void Push(Collider hitCollider)
{
    ForceVelocityCalculator forceVelocityCalculator = hitCollider.GetComponent<ForceVelocityCalculator>();
    if (forceVelocityCalculator != null)
    {
        forceVelocityCalculator.Push(_pushForce, GameAPI.playerTransform.transform.forward);
    }
}

뭔가가 빠졌나요? 두 블록 모두에 널 전파를 사용합니다.


  • 답변 # 1

    단일 객체에 대한 null 전파 사용 (구성 요소가 상속 한잘못된) 때문에 Resharper는 제안하지 않지만 Visual Studio 2019는 실제로 경고를 표시합니다.

    왜 pyzwyz를 제안합니까?  그러나 ? 인터페이스이기 때문에 IDE (코드 편집기)는이 인터페이스 인스턴스가 런타임 전에 어떤 유형의 객체를 나타내는 지 알지 못합니다.

    인터페이스가 IDamageable 에서 상속하지 않기 때문에 허용합니다 (또는 경고하지 않지만 런타임에 전파가 예상대로 작동하지 않습니다)  분명히, 그러나 UnityEngine.Object   ForceVelocityCalculator 에서 상속  또는 MonoBehaviour ScriptableObject 가있는  null 점검을 무효화하는 궁극적 인 부모로서, 이는 C # 언어에서의 널 전파가 단일체에 대한 널 점검과 동일하지 않음을 의미합니다.

    유니는 UnityEngine.Object 와 특별한 일을한다  운영자. 대부분의 사람들이 기대하는 것 대신 ( == 가 아닌 C # 언어로)  Unity)에는 UnityEngine.Object 의 특별한 구현이 있습니다.  연산자.

    이 두 가지 용도로 사용됩니다 :

    <올>

    와이즈 비즈  편집기에만 필드가 있습니다. unity는 해당 필드를 "실제 널"로 설정하지 않고 "가짜 널"오브젝트로 설정합니다. 및 사용자 정의 ==  운영자는 이러한 가짜 null 개체 중 하나가 무엇인지 확인할 수 있으며 그에 따라 동작합니다.

    이것은 이국적인 설정이지만, 유니티는 가짜 null 객체에 정보를 저장하여 메소드를 호출 할 때 또는 객체에 속성을 요청할 때보다 상황에 맞는 정보를 제공합니다.

    이 트릭이 없으면 오직 MonoBehaviour 만 얻을 수 있습니다 , 스택 추적이지만 어떤 == 를 모를 것입니다.   NullReferenceException 를했다  그 필드는 널이었습니다. 이 트릭으로 통일은 GameObject 를 강조 표시 할 수 있습니다  "이 MonoBehaviour 에서 초기화되지 않은 필드에 액세스하는 것처럼 보입니다.  여기에서 인스펙터를 사용하여 필드가 무언가를 가리 키도록합니다. "

    GameObject 유형의 C # 객체를 얻는 경우 거의 아무것도 포함하지 않습니다. Unity는 C/C ++ 엔진이기 때문입니다. 이 MonoBehaviour 에 대한 모든 실제 정보  (이름, 구성 요소 목록, GameObject 등)은 C ++쪽에 있습니다. c # 객체에있는 유일한 것은 네이티브 객체에 대한 포인터입니다.

    이 c # 객체를 "래퍼 객체"라고 부를 수 있습니다. GameObject 와 같은 C ++ 객체의 수명  그리고 HideFlags 에서 파생되는 다른 모든 것  명시 적으로 관리됩니다. 이 장면들은 새로운 장면을로드 할 때 파괴됩니다. 또는 GameObject 에 전화 할 때  그들에.

    c # 객체의 수명은 가비지 수집기를 사용하여 c # 방식으로 관리됩니다. 이것은 이미 존재하는 c # 래퍼 객체를 가지고 이미 파괴 된 c ++ 객체를 감싸는 것이 가능하다는 것을 의미합니다. 이 오브젝트를 null과 비교하면이 경우 실제 c # 변수가 실제로 null이 아니더라도 Unity의 custom == 연산자는 "true"를 반환합니다.그러나 null 전파는 다음과 같이 말합니다. 와이즈 비즈  백본이 존재하지 않을 때, 여전히 살아있는 외관 만 있으면 여전히 존재합니다.

    소스

  • 답변 # 2

    아마도 Unity가 UnityEngine.Object 에서 돌아 오는 것을 어떻게 정의했는지에 따라

    실제로GetComponent의 기능을 살펴보면 실제로절대Object.Destroy(myObject); 를 반환하지 않습니다. C # 코드와 Unity의 기본 C ++ 코드 간의 통신을 처리하는 객체 래퍼를 항상 얻습니다.

    그래서 UnityEngine.Object 에서 "널"을 얻을 때  실제로 얻는 것 (Unity가 GetComponent() 를 재정의했습니다.  operator!)는 실제로 null이 아니지만 객체 래퍼around null 입니다. . 따라서 ReSharper는 null 전파가 여기에 도움이 될 것임을 알지 못합니다 (물론 작동한다고 가정합니다 : 객체가실제로null이 아니기 때문에 null 인 척하기 때문에 구문 설탕은 그렇지 않을 수도 있습니다 제대로 작동하십시오!)

    GetComponent()

  • 이전 들여 쓰기를 수정하는 방법? haskell - 입력 '|'에서 구문 분석 오류
  • 다음 java - 계속 명령이 필요합니까? 왜?