[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来解决这个问题吗?
评论中建议,你不能将base转换为derive:,但实际上,我已经在我的视图中成功地完成了这一操作,只是在controller action中无法使用。
CitySearchCriteria citySearchCriteria = (CitySearchCriteria)Model.SearchCriteria;
这个转换成功了 为什么在控制器操作中不能成功呢?
每个人都已经(而且是正确的)告诉了你,你根本不能从Base到Derived的转换,但是在我看来,你似乎仍然没有明白为什么这一行在你的另一章代码中可以工作。
CitySearchCriteria citySearchCriteria = (CitySearchCriteria)Model.SearchCriteria;
我认为你对一个实例的 "类型 "是什么有点困惑。你没有发布Model的定义,但我认为你有这样的东西。
public SearchCriteria SearchCriteria;
这并不是说SearchCriteria总是包含SearchCriteria的实例 而是说它包含了可以投向SearchCriteria的类型的实例。在你的例子中,它可以包含SearchCriteria或CitySearchCriteria的实例。我想在你的代码中的某个地方你会发现类似这样的东西。
Model.SearchCriteria = new CitySearchCriteria();
这就是让你的投递正确执行的原因。你可以看到这个实例确实是一个CitySearchCriteria(而不是简单的SearchCriteria的实例)在投递之前执行了这段代码。
MessageBox.Show(Model.SearchCriteria.GetType().FullName);
为了更好地理解,你可以尝试在你的工作投递之前修改SearchCriteria的值,如下图所示,结果发现投递不再有效了。
Model.SearchCriteria = new SearchCriteria();
MessageBox.Show(Model.SearchCriteria.GetType().FullName);
CitySearchCriteria citySearchCriteria = (CitySearchCriteria)Model.SearchCriteria;
你不能这样投射!
如果你这样做 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
除非你想显式地测试一个对象是否属于该类型。
你可以创建CitySearchCriteria,并将其转换为SearchCriteria。这样你就只能看到CountryId。之后,你可以把它转回CitySearchCriteria,并看到CountryId和CityId。
这与DataContract无关。在你的情况下,解决方案是创建CitySearchCriteria,然后把它转为SearchCriteria(如果你需要的话)。