[DataContract]
public class SearchCriteria
{
[DataMember]
public string CountryID { get; set; }
}
[DataContract]
public class CitySearchCriteria: SearchCriteria
{
[DataMember]
public string CityID { get; set; }
}
我正在我的MVC控制器操作中创建一个SearchCriteria实例,并尝试 将其转换为CitySearchCriteria。
SearchCriteria searchCriteria = new SearchCriteria();
searchCriteria.CountryID = "1";
CitySearchCriteria citySearchCriteria = searchCriteria as CitySearchCriteria;
上述语句后的“citySearchCriteria”对象显示NULL值。我希望它显示属性,CountryID和CityID,其中CountryID已填充,CityID为空......但它将对象设置为NULL。
这里有什么解决方案? DataContract有什么用呢?
评论建议,你不能将基数转换为派生: 但实际上,我已经在我看来成功完成了这项工作,它只是在控制器操作中不起作用:
CitySearchCriteria citySearchCriteria = (CitySearchCriteria)Model.SearchCriteria;
这是成功转换的,为什么类似的东西不能在控制器动作中工作呢?
答案 0 :(得分:7)
你不能这样投!
如果执行new
,则会创建一个特定大小的新内存对象。在你的情况下,new SearchCriteria()
创建一个新的内存对象,其大小足以容纳一个字符串,仅此而已。
在最后一行中,您searchCriteria as CitySearchCriteria
尝试将searchCriteria
中的对象投射到更大的类型CitySearchCriteria
。但它无法完成。您正在尝试将包含1个字符串的内存对象“转换”为可容纳2个字符串的内存对象。但是转换不会转换新的内存对象。新字符串的价值是多少?它只是在水下查看您的引用searchCriteria
是否已包含CitySearchCriteria
类型的对象。在您的情况下:它不是(对象的类型为SearchCriteria
)并返回null
。
所以......下一个例子可以工作(因为已经创建了CitySearchCriteria)。这也是你的解决方案:
SearchCriteria searchCriteria = new CitySearchCriteria();
CitySearchCriteria citySearchCriteria = searchCriteria as CitySearchCriteria;
无法正常工作(因为尚未创建CitySearchCriteria)。这是你的情况:
SearchCriteria searchCriteria = new SearchCriteria();
CitySearchCriteria citySearchCriteria = searchCriteria as CitySearchCriteria;
与下一个例子相同。
可以正常工作(因为已经创建了SearchCriteria):
object o = new SearchCriteria();
SearchCriteria searchCriteria = o as SearchCriteria;
这样做不(因为尚未创建SearchCriteria)::
object o = new object();
SearchCriteria searchCriteria = o as SearchCriteria;
对于记录:我总是使用直接强制转换,而不是使用as
的强制转换,除非您要显式测试对象是否属于该类型。
答案 1 :(得分:5)
每个人都已经(并且正确地)告诉过你,你根本无法从Base转换为Derived,但在我看来,你仍然无法理解为什么这条线在你的代码的另一块中工作:< / p>
CitySearchCriteria citySearchCriteria = (CitySearchCriteria)Model.SearchCriteria;
我认为你对实例的“类型”有点困惑。你没有发布模型的定义,但我认为你有这样的东西:
public SearchCriteria SearchCriteria;
这并不意味着SearchCriteria始终包含SearchCriteria的实例,而只是包含可以强制转换为SearchCriteria的类型实例。在您的情况下,它可以包含SearchCriteria或CitySearchCriteria的实例。我想在你的代码中的某个地方你会找到类似的东西:
Model.SearchCriteria = new CitySearchCriteria();
这是允许正确执行yor强制转换的原因。你可以看到实例确实是一个CitySearchCriteria(而不仅仅是SearchCriteria的一个实例)在演员表之前执行这段代码:
MessageBox.Show(Model.SearchCriteria.GetType().FullName;
为了更好地理解你可以尝试在工作演员之前修改SearchCriteria中的值,如下所示,只是为了发现演员阵容不再有效:
Model.SearchCriteria = new SearchCriteria();
MessageBox.Show(Model.SearchCriteria.GetType().FullName;
CitySearchCriteria citySearchCriteria = (CitySearchCriteria)Model.SearchCriteria;
答案 2 :(得分:2)
您可以创建CitySearchCriteria,并将其投射到SearchCriteria。这样你只能看到CountryId。稍后,您可以将其强制转换回CitySearchCriteria,并查看CountryId和CityId。
这与DataContract无关。您的案例中的解决方案是创建CitySearchCriteria并将其投射到SearchCriteria(如果您需要)。