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