다른 클래스로 암시 적으로 변환하는 유일한 목적을 가진 클래스를 만드는 것은 좋지 않습니까?


10

Circle객체 를 생성 할 수있는 라이브러리를 사용하는 상황을 상상해보십시오. 여기 에서 원의 반경과 중심을 지정하여 객체를 정의 할 수 있습니다. 그러나 어떤 이유로 든 필수 flavour매개 변수 도 필요합니다 . 이제 Circle내 앱에서 실제로 사용해야한다고 가정 해 봅시다 .하지만 내 앱의 목적을 위해 Flavours.Cardboard매번 맛을 설정할 수 있습니다 .

이 "해결"을 위해, 나는 내 자신의 생성 Circle만을 취하는 다른 네임 스페이스에 클래스를 radius하고 center매개 변수로하지만, 외부 라이브러리에 대한 암시 적 변환이 Circle단지 생성 클래스 Circle(this.radius, this.center, Flavours.Cardboard)개체를. 따라서 다른 유형의이 필요한 모든 곳 Circle에서 자동 변환이 수행되도록합니다.

그러한 클래스를 만들면 어떤 결과가 있습니까? 더 나은 솔루션이 있습니까? 내 응용 프로그램이 다른 프로그래머가 사용하도록 설계된이 외부 라이브러리 위에 구축 된 API라면 어떤 차이가 있습니까?


이것은 어댑터 패턴 의 변형처럼 보이지만 여기서는 모호한 가치가있는 것 같습니다 (매개 변수 설정을 피하기위한 편의 일뿐입니다).
Robert Harvey

5
MakeCircle 함수를 작성하지 않습니까?
user253751

1
@immibis Thay는 나의 첫 생각이었습니다. 게임을 만들 때 종종 makePlayer그 자체 의 라인을 따라 함수를 만들 것입니다. 그 자체로 플레이어를 배치하기위한 좌표 만 허용하지만 훨씬 더 복잡한 생성자에게 위임합니다.
Carcigenicate

답변:


13

항상 나쁜 것은 아니지만 암시 적 전환이 최선의 선택이라는 것은 매우 드 rare니다.

문제가 있습니다.

  1. 암시 적 변환은 읽기 쉽지 않습니다.
  2. 새 개체를 만들고 있기 때문에 변환중인 개체가 원래 개체에 대한 변경 내용을 볼 수 없으므로 버그가 발생합니다.
  3. 물건을 버릴 때는 여분의 쓰레기가 필요합니다.
  4. 문제가 발생하면 문제가 발생했을 때가 아니라 변환이 발생할 때 발생하여 버그를 찾기가 더 어려워집니다.

일반적으로 더 나은 솔루션이 있습니다.

  1. 다른 클래스 / 프레임 워크를 내부적으로 사용하는 얇은 랩퍼를 만드십시오.
  2. 원하는 constuctor 인수를 가져오고 고정 된 것을 제공하는 도우미 메서드를 만들고 관심없는 인수를 지정하지 않고 실제 객체를 반환하십시오.
  3. 문제 클래스에서 상속하고 자신 만의 멋진 생성자를 제공하십시오.
  4. 추가 인수를 전달하는 것이 실제로 그렇게 큰 일이 아님을 인식하십시오.

개인적으로, # 2는 구현하기가 가장 간단하고 디자인에 가장 부담이 적은 것으로 나타났습니다. 상황 과이 수업으로 무엇을하려고하는지 고려할 때 다른 사람들은 괜찮을 수 있습니다.

암시 적 변환은 최후의 수단이며, C ++ 스타일 펑터를 만들려고 할 때만 가치가있는 것처럼 보입니다.


1

설명하고있는 시나리오를 고려할 때 부분 기능 적용 측면에서이를 생각할 수 있습니다.

생성자는 함수입니다 (적어도 이론적으로는 C #에서는 생성자를 호출하는 "공장 함수"를 만들 수 있습니다).

Func<double, Point, Flavour, Circle> MakeCircle = (r, p, f) => new Circle(r, p, f);

부분 적용의 경우 다음이 충분합니다.

public static Func<T1, T2, R> Partial<T1, T2, T3, R>(this Func<T1, T2, T3, R> func, T3 t3)
   => (t1, t2) => func(t1, t2, t3);

이제 2 개의 매개 변수 만 필요한 생성자를 얻을 수 있습니다.

Func<double, Point, Circle> MakeCardboardCircle = Circle.Partial(Flavours.Cardboard)

이제 원하는 매개 변수가있는 공장 기능이 있습니다.

Circle c = MakeCardboardCircle(1.0, new Point(0, 0)))

BTW, 이것은 기능적 관점에서 위의 옵션 2와 분명히 동일합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.