문제

파생 클래스를 사용하고 있으며 as 키워드를 사용하여 기본 클래스를 해당 클래스에 캐스팅하고 있습니다.이 작업을 수행하면 파생 클래스 생성자가 호출되고 개체가 초기화되지만 파생 인스턴스는 초기화된 개체(null 포함)로 끝나지 않습니다.다음은 코드 샘플입니다.

// classes
public class Request
{
  public Request();
  public Header Header{get;set;}
}

public class CreateRequest : Request
{
  public Foo Foo{get;set;}
  public Bar Bar{get;set;}

  public CreateRequest():base()
  {
    this.Foo = new Foo();
    this.Bar = new Bar();
  }
}

public class SomeClass
{
  private Response ProcessCreateRequest(Request request)
  {
    // request comes from a json request
    CreateRequest createRequest = request as CreateRequest;
    // values of Foo and Bar are null
    [...]
  }
}

"as"가 일반적으로 파생->기본에 사용되고 기본->파생이 아닌 문제가 있습니까? 아니면 여기서 다른 작업이 있습니까?

도움이 되었습니까?

해결책

jon skeet이 이 질문에 정확하게 대답하기 전까지는 내가 아는 한 'as' 키워드는 캐스트가 유효하지 않은 경우 예외를 억제하는 캐스트를 수행하는 방법일 뿐입니다.자체적으로 생성자를 호출해서는 안 됩니다.

그래서 확인하셨나요(예:디버거에서) 전달된 개체가 캐스팅 전에 올바르게 초기화되었는지 확인하세요.

다른 팁

명확히 하자면, as 연산자는 해당 개체에 대해 어떤 메서드도 호출하지 않습니다.단지 객체가 요청된 유형으로 변환될 수 있는지 확인하고, 그렇다면 인스턴스를 유형 또는 유형으로 반환합니다. null 그렇지 않은 경우(C# 언어 사양 섹션 7.9.11 "as 연산자" 참조)

표시된 코드에 따르면 다음과 같은 이유가 없는 것으로 보입니다. CreateRequest 갖다 null JSON 요청 역직렬화 메서드가 명시적으로 null로 설정하지 않는 한 속성입니다.다음을 호출하여 이것이 사실임을 보여줄 수 있습니다.

var response = ProcessCreateRequest(new CreateRequest());
System.Diagnostics.Debug.Assert(response.Foo != null);
System.Diagnostics.Debug.Assert(response.Bar != null);

당신은 둘 다 찾을 수 있습니다 as 연산자와 기본 생성자가 올바르게 작동합니다.

문제는 'as'를 사용하면 생성자를 호출하지 않는다는 것입니다.단지 객체를 새로운 유형(이 경우 Request에서 CreateRequest로)으로 캐스팅합니다.

귀하의 경우 요청에 필드 값이 없으므로 캐스팅 후 null입니다.

"as" 키워드를 사용하여 기본 클래스의 인스턴스를 파생 클래스의 인스턴스로 변환할 수 없습니다.객체가 처음부터 파생 클래스의 인스턴스가 아닌 경우 "as" 키워드는 이를 인스턴스로 변환하지 않습니다.

또한 stephan이 말한 것 외에도 ('as'를 사용하면 생성자를 실행할 수 없습니다),

...당신의 질문에 당신은 이렇게 말했어요

"파생 클래스를 사용하고 기본 클래스를 여기에 캐스팅하고 있습니다..."

기본 클래스를 파생 클래스로 캐스팅할 수 없으며 그 반대 방향으로만 캐스팅할 수 있으므로 (희망적으로) 질문을 잘못 언급했거나 가정이 어떤 방식으로 유효하지 않습니다.좀 더 명확하게 말할 수 있나요?

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top