>

오브젝트 캐스팅은 나쁜 습관이며, 예를 들어 주조를 피해야하는 이유는 무엇인가요? 질문에 다음과 같은 큰 논거가 있습니다.

<올>
  • 제리 관으로 :

    Looking at things more generally, the situation's pretty simple (at least IMO): a cast (obviously enough) means you're converting something from one type to another. When/if you do that, it raises the question "Why?" If you really want something to be a particular type, why didn't you define it to be that type to start with? That's not to say there's never a reason to do such a conversion, but anytime it happens, it should prompt the question of whether you could re-design the code so the correct type was used throughout.

  • 에릭 리퍼로 :

    Both kinds of casts are red flags. The first kind of cast raises the question "why exactly is it that the developer knows something that the compiler doesn't?" If you are in that situation then the better thing to do is usually to change the program so that the compiler does have a handle on reality. Then you don't need the cast; the analysis is done at compile time.

    The second kind of cast raises the question "why isn't the operation being done in the target data type in the first place?" If you need a result in ints then why are you holding a double in the first place? Shouldn't you be holding an int?

  • 질문으로 넘어 가면서 최근에 잘 알려진 오픈 소스 프로젝트AutoFixture는 원래 Mark Seemann에 의해 개발되었으며 정말 감사합니다.

    라이브러리의 주요 구성 요소 중 하나는 ISpecimenBuilder 추상적 인 방법을 정의합니다 :

    object Create(object request, ISpecimenContext context);
    
    

    요청 매개 변수 유형이 객체라는 것을 알 수 있듯이 완전히 다른 유형을 허용하므로 인터페이스의 다른 구현은 런타임 유형에 따라 다른 요청을 처리하여 케이블이 처리하는 것이 아닌지 여부를 확인합니다. 표현.

    인터페이스 디자인은 객체 캐스팅이 드물게 사용되어야하는 "좋은 방법"을 따르지 않는 것 같습니다.

    모든 주물을 물리 치지 만 해결책을 찾을 수없는 방식으로이 계약을 설계하는 더 좋은 방법이 있는지 스스로 생각하고있었습니다.
    분명히 객체 매개 변수는 일부 마커 인터페이스로 대체 될 수 있지만 주조 문제를 저장하지는 못합니다. 또한 여기 그러나 확장 성이 뛰어나지는 않지만 방문자는 수십 가지의 다른 방법을 가져야합니다. 다양한 유형의 요청을 처리 할 수있는 인터페이스

    이 특정 시나리오에서 좋은 디자인의 일부로 캐스팅을 사용하는 것에 대한 주장에 기본적으로 동의한다는 사실은 최선의 선택 일뿐 만 아니라 유일한 현실적인 것 같습니다.

    요약하면, 모듈 식 및 확장 가능한 아키텍처를 설계해야 할 때 객체 캐스팅과 매우 일반적인 계약이 현실에서 불가피합니까?


    • 답변 # 1

      어떤 유형의 응용 프로그램이나 프레임 워크에 대해서도이 질문에 일반적으로 대답 할 수는 없다고 생각하지만, 자동 사용에 대해 구체적으로 이야기하고 다른 사용 시나리오에 대한 추측을 제공하는 답변을 제공 할 수 있습니다.

      오늘부터 AutoFixture를 처음부터 작성해야한다면 분명히 다르게해야 할 일이 있습니다. 특히, 나는 ISpecimenBuilder 와 같은 것을 중심으로 일상적인 API를 설계하지 않을 것입니다. . 대신 여기에 설명 된대로 펑터 및 모나드 개념을 중심으로 데이터 조작 API를 디자인했습니다.

      이 디자인은 전적으로 제네릭을 기반으로하지만 컴파일 타임에 알려진 정적으로 유형이 지정된 빌딩 블록이 필요합니다 (

      ).

      이것은 QuickCheck와 같은 방식과 밀접한 관련이 있습니다. QuickCheck 기반 테스트를 작성할 때는 모든 사용자 정의 유형에 대해 생성기를 제공해야합니다. Haskell은 런타임 값 캐스팅을 지원하지 않지만 대신 제네릭과 일부 컴파일 타임 자동화에만 의존합니다. 물론 Haskell의 제네릭은 C #보다 강력하므로 Haskell에서 얻은 지식을 C #으로 이전 할 필요는 없습니다. 그러나 런타임 캐스팅에 의존하지 않고 코드를 완전히 작성할 수 있다고 제안합니다.

      그러나 AutoFixture는 사용자 정의 생성기를 작성할 필요없이 사용자 정의 유형을 지원합니다. .NET Reflection을 통해이 작업을 수행합니다. .NET에서 Reflection API는 형식이 지정되지 않습니다. 객체를 생성하고 멤버를 호출하는 모든 방법은 object 를 사용합니다.  입력 및 리턴 object  출력으로.

      Reflection을 기반으로하는 모든 응용 프로그램, 라이브러리 또는 프레임 워크는 런타임 캐스팅을 수행해야합니다. 그 문제를 해결하는 방법을 모르겠습니다.

      반사없이 데이터 생성기를 작성할 수 있습니까? 나는 다음을 시도하지 않았지만 아마도 IL에서 직접 데이터 생성기에 대한 '코드'를 작성하고Reflection emit을 사용하여 메모리 내 어셈블리를 동적으로 컴파일하는 전략을 채택 할 수 있습니다 생성기를 포함합니다.

      이것은 Hiro 컨테이너의 작동 방식과 비슷합니다. IIRC. 이 개념을 중심으로 다른 유형의 범용 프레임 워크를 디자인 할 수 있다고 생각하지만 .NET에서는 거의 볼 수 없습니다.

    관련 자료

  • 이전 javascript - 장고 템플릿 API 요청으로 인해 페이지에서 검색어 URL로 이동
  • 다음 android - Java에서 Kotlin으로 코드를 변경 한 후 주석이 올바르게 변환되지 않음