Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 无法将基类(数据协定)强制转换为派生类_C#_Oop_Casting_Datacontract_Derived Class - Fatal编程技术网

C# 无法将基类(数据协定)强制转换为派生类

C# 无法将基类(数据协定)强制转换为派生类,c#,oop,casting,datacontract,derived-class,C#,Oop,Casting,Datacontract,Derived Class,我正在MVC控制器操作中创建SearchCriteria实例,并尝试 将其转换为CitySearchCriteria [DataContract] public class SearchCriteria { [DataMember] public string CountryID { get; set; } } [DataContract] public class CitySearchCriteria: SearchCriteria { [DataMember

我正在MVC控制器操作中创建SearchCriteria实例,并尝试 将其转换为CitySearchCriteria

[DataContract]
public class SearchCriteria
{
    [DataMember]
    public string CountryID { get; set; }    
}

[DataContract]
public class CitySearchCriteria: SearchCriteria
{
    [DataMember]
    public string CityID { get; set; }
}
上述语句后面的“citySearchCriteria”对象显示空值。我希望它同时显示属性,CountryID和CityID,其中CountryID已填充,CityID为空。。。但它正在将对象设置为NULL

这里的解决方案是什么?DataContract与此有关吗

注释建议,不能将基转换为派生: 但事实上,在我看来,我已经成功地做到了这一点,只是在控制器操作中不起作用:

SearchCriteria searchCriteria = new SearchCriteria();
searchCriteria.CountryID = "1";
CitySearchCriteria citySearchCriteria = searchCriteria as CitySearchCriteria;

这是成功的转换,那么为什么类似的东西不能在控制器操作中工作呢?

您不能以这种方式强制转换

如果执行
new
操作,将创建一个特定大小的新内存对象。在您的例子中,
new SearchCriteria()
创建一个新的内存对象,其大小足以容纳一个字符串,不能多,也不能少

在最后一行中,您尝试将
searchCriteria作为CitySearchCriteria
中的对象强制转换为更大的类型
CitySearchCriteria
。但这是不可能做到的。您正在尝试将一个包含1个字符串的内存对象“转换”为一个包含2个字符串的内存对象。但强制转换不会转换新的内存对象。新字符串的值是多少?它只是在水下查看您的引用
searchCriteria
是否已包含类型为
CitySearchCriteria
的对象。在您的情况下:它不会(对象类型为
SearchCriteria
)并返回
null

所以。。。下一个示例确实有效(因为已经创建了CitySearchCriteria)。这也是您的解决方案:

CitySearchCriteria citySearchCriteria = (CitySearchCriteria)Model.SearchCriteria;
这不起作用(因为还没有创建CitySearchCriteria)。这就是你的情况:

SearchCriteria searchCriteria = new CitySearchCriteria(); 
CitySearchCriteria citySearchCriteria = searchCriteria as CitySearchCriteria;
这与下一个示例相同。
确实有效(因为已创建搜索条件):

而这不是(因为还没有创建搜索条件):


作为记录:我将始终使用直接强制转换,而不是使用
as
的强制转换,除非您希望明确测试对象是否属于该类型。

您可以创建CitySearchCriteria,并将其强制转换为SearchCriteria。这样您只能看到CountryId。稍后,您可以将其转换回CitySearchCriteria,并查看CountryId和CityId

这与DataContract无关。您的解决方案是创建CitySearchCriteria并将其转换为SearchCriteria(如果您需要)。

每个人都已经(正确地)告诉过您,您无法从基转换为派生,但在我看来,您仍然不明白为什么这一行可以在您的另一段代码中工作:

object o = new object();
SearchCriteria searchCriteria = o as SearchCriteria;
我认为您对实例的“类型”有点困惑。您没有发布模型的定义,但我认为您有如下内容:

CitySearchCriteria citySearchCriteria = (CitySearchCriteria)Model.SearchCriteria;
这并不意味着SearchCriteria总是包含SearchCriteria的实例,只是它包含可以转换为SearchCriteria的类型的实例。在您的情况下,它可以包含SearchCriteria或CitySearchCriteria的实例。我想在您的代码中,您会发现如下内容:

public SearchCriteria SearchCriteria;
这就是让你的演员能够正确执行的原因。您可以看到,该实例实际上是一个CitySearchCriteria(而不仅仅是SearchCriteria的实例),在强制转换之前执行以下代码:

Model.SearchCriteria = new CitySearchCriteria();
为了更好地理解,您可以尝试在工作强制转换之前修改SearchCriteria中的值,如下所示,但发现强制转换不再工作:

MessageBox.Show(Model.SearchCriteria.GetType().FullName);

不能从基转换为派生。相反的情况是可能的。请参阅问题的最后两段再次检查Martin的答案(第一个示例)。它无法转换,因为根据他的实现,转换将无法从基类转换为派生类。相反是可能的。我想这正是我所说的。。。不是吗?还是我不明白你的意思?我课文中的哪个例子不正确?是的,第三个可以。对象可以包含任何类型。您可以将其强制转换为任何类型,只要它保持该类型。另一个例子是:
objecto=“Hello”;字符串s=o作为字符串Model.SearchCriteria = new CitySearchCriteria();
MessageBox.Show(Model.SearchCriteria.GetType().FullName);
Model.SearchCriteria = new SearchCriteria();
MessageBox.Show(Model.SearchCriteria.GetType().FullName);
CitySearchCriteria citySearchCriteria = (CitySearchCriteria)Model.SearchCriteria;