1

我正在使用派生类并使用 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
    [...]
  }
}

问题是“as”通常用于派生->基础而不是基础->派生,还是这里有其他工作?

4

5 回答 5

7

直到 jon skeet 出现以正确回答这个问题,据我所知,'as' 关键字只是一种进行强制转换的方法,如果强制转换无效,它会抑制异常;它不应该自己调用任何构造函数

那么您是否验证过(例如在调试器中)传入的对象在强制转换之前已正确初始化?

于 2009-08-17T17:01:23.240 回答
3

作为澄清点,as操作员不会在相关对象上调用任何方法。它只是查明对象是否可以转换为请求的类型,如果可以,则将实例作为类型返回,或者null是否不能(请参阅 C# 语言规范第 7.9.11 节“as 运算符”)。

从您显示的代码来看,除非 JSON 请求反序列化方法将它们显式设置为 null ,否则似乎没有理由CreateRequest拥有这些属性。null您可以通过调用以下方法来证明是这种情况:

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

您会发现as运算符和默认构造函数都正常工作。

于 2009-08-17T17:02:24.860 回答
1

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

在您的情况下,由于 Request 没有字段的值......它们在被转换后为空。

于 2009-08-17T17:02:44.297 回答
0

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

于 2009-08-17T17:08:26.097 回答
-1

此外,除了斯蒂芬所说的,(使用'as'不能触发构造函数),

...在你的问题中,你说

“我正在使用派生类并将基类转换为它......”

您不能将基类转换为派生类,只能反过来,所以很明显(希望)您错误地陈述了您的问题,或者您的假设在某种程度上是无效的。你能更明确一点吗?

于 2009-08-17T17:04:15.900 回答