2009-08-17 74 views
1

我正在使用派生类并使用as关键字将基类转换为它。当我这样做时,派生类构造函数被调用,并且它的对象被初始化,但派生实例不会以初始化对象(具有空值)结束。这是一个代码示例。使用“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->的基础,而不是碱基问题>派生或者是有工作别的东西吗?

回答

7

直到jon双向游戏显示正确回答这个问题,据我所知'as'关键字只是一种方法来执行强制转换,如果强制转换无效,则会抑制异常;它不应该自己调用任何构造函数

因此,您是否验证过(例如,在调试器中)传入的对象在投射之前是否已正确初始化?

+0

+1你说的没错,只有'只铸造 - 没有构造函数被调用。 – 2009-08-17 17:02:55

+0

我已经验证的是构造函数被击中。我实际上试图解决的是一个请求没有指定所有主体参数的情况。这杀了我,因为我到了对象结构中,进来的null表示一个空对象,当访问成员时它将开始抛出异常。我可以在演员阵容中捕捉到空洞,但似乎应该有一种更优雅地照顾它的方法。 – TahoeWolverine 2009-08-17 19:41:09

+0

您应该检查JSON请求解串器是否正常工作。所以至少抛出一个不完整请求的异常。 – user7116 2009-08-17 20:17:02

3

作为澄清的一点,as运算符不会调用有关对象上的任何方法。它只是发现对象是否可以转换为请求的类型,如果是,则返回实例作为类型或如果不能(返回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运营商和默认的构造函数工作正常。

+0

+1这也是正确的,因为不会调用用户定义的转换。请参阅http://msdn.microsoft.com/en-us/library/cscsdfbt(VS.71).aspx – 2009-08-17 17:05:51

+0

是的7.9.11与以下内容拼写:“请注意,某些转换(例如用户定义的转换)不可行使用as运算符,而应该使用强制表达式来执行。“ – user7116 2009-08-17 17:09:21

1

问题是使用'as'不会调用构造函数。它只是将对象转换为新类型(在这种情况下,从Request到CreateRequest)。

就你的情况而言,由于Request没有字段值......在投射后它们为空。

+0

如果Request不是CreateRequest,那么'as'-cast将返回null。默认构造函数创建具有非空值的属性,因此在JSON反序列化中的某处,属性被设为null。 – user7116 2009-08-17 17:04:16

+1

我们正在谈论C#...... JSON从哪里来? – 2009-08-17 17:07:55

+1

他的代码表示(或者说暗示)Request对象是由JSON请求反序列化产生的。 – user7116 2009-08-17 17:11:04

-1

此外,除了什么斯蒂芬说,(使用“作为”不能触发构造函数),

...在年的问题,你的状态

“我使用的是派生类将基类投射到它上面...“

您不能将基类转换为派生类,只能以相反方式,很清楚地(希望)您错误地陈述年代问题,或者您的假设无效某种程度上来说。你能更明确吗?

+0

当且仅当派生类从相关基类派生时,才可以将基类转换为派生类。 – user7116 2009-08-17 17:12:37

+0

@sixletter ...,你完全向后...你不能将一个基类的实例转换为派生类的类型。即。如果构建Animal的实例,则不能将该实例转换为输入Pig。 otoh,如果你有一个猪的实例,你可以将它转换成动物类型... – 2009-08-19 02:35:18

0

不能使用“as”关键字将基类的实例转换为派生类的实例。如果对象不是派生类的实例,那么“as”关键字将不会将其转换为一个。

+0

那么,在这种情况下,它是,有点。处理JSON请求时,请求中的参数与类的成员匹配。我的问题是,如果有人提出请求,说没有身体,那么请求对象中的对象开始在访问其成员时抛出异常。 – TahoeWolverine 2009-08-17 19:46:05