오브젝트 캐스팅은 나쁜 습관이며, 예를 들어 주조를 피해야하는 이유는 무엇인가요? 질문에 다음과 같은 큰 논거가 있습니다.
<올>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
관련 자료
- javascript - 객체에서 객체를 배열로 푸시하는 방법이 있습니까? (Vue)
- objective c - 배경 dispatch_queue에서 ObjC 객체를 초기화하는 좋은 방법이 있습니까?
- c++ - 개체를 선언/정의하는 데 사용되는 h 파일을 #includes 프로젝트의 기본 프로그램 파일에서 개체 멤버 배열 크기를 설정하는 방법이 있습니까?
- JAVA, 내 출력에서 ArrayList의 객체 이름을 표시하는 방법이 있습니까?
- java - Method []에서 객체를 제거하는 방법이 있습니까?
- drupal - Request 객체 또는 다른 서비스 클래스에서 컨트롤러 클래스를 가져 오는 방법이 있습니까?
- python - 객체를 해결하는 방법이 FindAll () 속성이 없습니까?
- java - 데이터와 재정의 된 toString 메서드를 사용하여 익명 개체 배열을 만드는 방법이 있습니까?
- r - cowplot 개체의 테마를 조정하는 방법이 있습니까?
- typescript가 arguments 객체를 추론하거나 arguments 객체에 대해 유형을 정의하는 방법이 있습니까?
- typescript - 빈 개체에 대해 약한 유형 감지가없는 이유
- tensorflow - tensorflow_hubKerasLayer 객체의 레이어에 액세스하는 방법이 있습니까?
- java - Object 클래스로 캐스팅 할 때 제네릭이 필요한 이유는 무엇입니까?
어떤 유형의 응용 프로그램이나 프레임 워크에 대해서도이 질문에 일반적으로 대답 할 수는 없다고 생각하지만, 자동 사용에 대해 구체적으로 이야기하고 다른 사용 시나리오에 대한 추측을 제공하는 답변을 제공 할 수 있습니다.
오늘부터 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에서는 거의 볼 수 없습니다.