2009-08-17 4 views
1

파생 클래스를 사용하고 as 키워드를 사용하여 기본 클래스를 캐스팅했습니다. 이렇게하면 파생 클래스 생성자가 호출되고 개체가 초기화되지만 파생 인스턴스가 초기화 된 개체 (null이 있음)로 끝나지 않습니다. 다음은 코드 샘플입니다."as"키워드를 사용하여 개체 초기화가 손실되었습니다.

// 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 
    [...] 
    } 
} 

"로"일반적으로 derived-> 기본 사용 및 BASE-되지 않는 문제> 파생 또는 직장에서 뭔가 다른 여기에있다?

답변

7

jon skeet이 정확하게이 질문에 답할 때까지 'as'키워드는 캐스트가 유효하지 않은 경우 예외를 억제하는 캐스트를 수행하는 방법임을 알고 있습니다. 자체 생성자를 호출하지 말아야합니다.

그래서 전달 된 객체가 형 변환 전에 제대로 초기화되었는지 (예 : 디버거에서) 확인 했습니까?

+0

+1 당신이 맞습니다,'단지'캐스트 - 아무 생성자도 호출되지 않습니다. –

+0

내가 확인한 것은 생성자가 충돌한다는 것입니다. 내가 실제로 풀려고하는 것은 모든 신체 매개 변수가 지정되지 않은 상태에서 요청이 들어오는 경우입니다. null이 오는 null 객체를 의미하는 객체 구조에 도착한 이후 멤버가 액세스 될 때 예외를 throw하기 시작합니다. 캐스트 한 후에 null 값을 잡을 수는 있지만 정상적으로 처리 할 수있는 방법이 있어야합니다. – TahoeWolverine

+0

JSON 요청 디시리얼라이저가 제대로 작동하는지 확인해야합니다.최소한 불완전한 요청에 대해서는 예외를 던지십시오. – user7116

3

설명의 요점으로 as 연산자는 해당 개체에 대한 메서드를 호출하지 않습니다. 단지 객체가 요청 된 유형으로 변환 될 수 있는지 여부를 알아 내고, 그렇다면 유형을 null으로 반환합니다 (C# 언어 사양 섹션 7.9.11 "as 연산자"참조).

표시 한 코드에서 null 속성을 가질 이유가 없다는 것을 알 수 있습니다 (JSON 요청 직렬화 메소드가이를 명시 적으로 null로 설정하지 않은 경우). 당신은 호출하여 이런 경우가 보여줄 수 :

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

당신은 as 연산자와 기본 생성자가 모두 제대로 작동 찾을 수 있습니다.

+0

+1 이것은 사용자 정의 변환을 호출하지 않기 때문에 올바른 것입니다. http://msdn.microsoft.com/en-us/library/cscsdfbt(VS.71).aspx 참조하십시오. –

+0

예 7.9.11은 다음과 같이 설명합니다. "사용자 정의 변환과 같은 일부 변환은 불가능합니다 as 연산자를 사용하고 대신 캐스트 식을 사용하여 수행해야합니다. " – user7116

1

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

요청에 필드 값이 없으므로 캐스팅 된 후 null입니다.

+0

요청이 CreateRequest가 아닌 경우 'as'-cast는 null을 반환합니다. 기본 생성자는 null이 아닌 값으로 속성을 만듭니다. 따라서 JSON 역 직렬화 어딘가에서 속성이 null이됩니다. – user7116

+1

우리는 C#을 말하고 있습니다 ... JSON은 어디에서 왔습니까? –

+1

그의 코드는 Request 객체가 JSON 요청 deserialization에 의해 만들어 졌다고 (또는 오히려 의미한다) 말합니다. – user7116

-1

또한, 또한 무엇 스테판에, 연간 질문에 ...

, (생성자를 실행할 수 없습니다 '로'사용), 당신은

을 언급 말했다 "나는 파생 클래스를 이용하고 있고 기본 클래스를 캐스팅 ... "

파생 클래스로 기본 클래스를 캐스팅 할 수 없으며, 다른 방법으로는 캐스트 할 수 없으므로 예기치 않은 질문이 있거나 가정이 유효하지 않습니다. 어떤 식 으로든. 더 노골적으로 표현할 수 있습니까?

+0

파생 클래스가 문제의 기본 클래스에서 파생되는 경우에만 기본 클래스를 파생 클래스에 캐스트 할 수 있습니다. – user7116

+0

@sixletter ... 기본 클래스의 인스턴스를 파생 클래스의 유형으로 캐스트 할 수 없습니다. 즉. Animal의 인스턴스를 구성하면 해당 인스턴스를 Pig 유형으로 변환 할 수 없습니다. 당신이 돼지의 인스턴스를 가지고 있다면, 당신은 그것을 Animal 타입으로 던질 수 있습니다 ... –

0

"as"키워드를 사용하여 기본 클래스의 인스턴스를 파생 클래스의 인스턴스로 변환 할 수 없습니다. 객체가 파생 클래스의 인스턴스가 아니라면, "as"키워드는 그것을 파생 클래스로 변환하지 않습니다.

+0

글쎄,이 경우에, 일종의. JSON 요청을 처리하면 요청에 들어오는 매개 변수가 클래스 멤버와 일치합니다. 내 문제는 사람이 전혀 본문없이 요청을하면 내 요청 개체 내의 개체가 멤버에게 액세스 할 때 예외를 throw하기 시작하는 것입니다. – TahoeWolverine

관련 문제