Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-mvc/16.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/arduino/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#_Asp.net Mvc_Generics_Interface - Fatal编程技术网

我是否可以将未知对象强制转换到接口,以便在C#中访问其属性?

我是否可以将未知对象强制转换到接口,以便在C#中访问其属性?,c#,asp.net-mvc,generics,interface,C#,Asp.net Mvc,Generics,Interface,我尽量不重复代码,所以我有一个方法可以对接口的属性进行快速转换 我有3个具体的类使用这个接口,我希望它们都能使用这个方法 当我从会话中获取其中一个对象时,问题就出现了。我看不出有什么办法能把它投好 public ActionResult GetItems() { details = (IHeader<IDetail>)Session["SelectedHeader"].Details // Throws invalid cast return Json(detai

我尽量不重复代码,所以我有一个方法可以对接口的属性进行快速转换

我有3个具体的类使用这个接口,我希望它们都能使用这个方法

当我从会话中获取其中一个对象时,问题就出现了。我看不出有什么办法能把它投好

public ActionResult GetItems()
{
     details = (IHeader<IDetail>)Session["SelectedHeader"].Details // Throws invalid cast
     return Json(details);
}

// My interface and class examples:
interface IHeader<T> where T: IDetail
{
     IList<T> Details { get; set; }
}

class ConcreteHeader : IHeader<ConcreteDetail>
{
     public IList<ConcreteDetail> Items { get; set; }
}

class ConcreteDetail : IDetail
{
    ...
}
public ActionResult GetItems()
{
详细信息=(IHeader)会话[“SelectedHeader”]。详细信息//抛出无效的强制转换
返回Json(详细信息);
}
//我的界面和类示例:
接口i头,其中T:IDetail
{
IList详细信息{get;set;}
}
类标题:IHeader
{
公共IList项{get;set;}
}
类具体细节:IDetail
{
...
}
我不能使用泛型,因为这是ASP.NET MVC 3中的一种操作方法(除非有技巧)。这是可能的,还是我必须为每个类编写一个方法

编辑:不确定这是否与原始问题一致:

进入会话的是任何一个具体对象:

Session["SelectedHeader"] = new ConcreteHeader() { Details = new List<ConcreteDetail>() };
Session[“SelectedHeader”]=newconcreteheader(){Details=newlist()};

您需要用括号括起您的演员阵容:

details = ((IHeader<IDetail>)Session["SelectedHeader"]).Details;
details=((IHeader)会话[“SelectedHeader”])。详细信息;

如果您使用的是.NET 4.0,只需使用
dynamic
关键字强制转换即可确保正确的自动类型分辨率:

// note intellisense won't work when you use dynamic keyword...
var details = ((dynamic)Session["SelectedHeader"]).Details;

似乎你刚刚进入了一个和谐与矛盾的奇妙世界。我写了一篇文章,试图尽可能简单地解释它

底线:在.NET4.0之前,您不能将
IHeader
转换为
IHeader

从.NET 4.0开始,您可以使用和关键字来实现这一点。您可以将接口定义为
接口IHeader

如果您尚未使用.NET 4.0,您可以通过创建新的lambda来解决此问题:


details=()=>Session[“SelectedHeader”]。详细信息

您是
ConcreteHeader
没有实现
IDetail
,但是您有一个
T:IDetail
的通用约束。这是如何编译的?@m-y,不应该
ConcreteDetail
实现
IDetail
?@Saeb是的,确实如此。我可以把它放进去澄清一下。@cmuffin,没必要。我是在回答m-y的问题。@IronicMuffin:如果您将
IDetail
实现为一个抽象类,则转换将起作用。刚刚完成测试。虽然您对我放错位置的参数的看法是正确的,但它仍然会抛出一个强制转换异常:
无法将“Session[“SelectedHeader”](实际类型为“ConcreteHeader”)强制转换为“IHeader”
尝试在
IHeader
上使用out关键字。我以前尝试过,但运气不太好。我现在添加了它,并得到以下结果:
无效的方差:类型参数“T”必须在“IHeader.Details”上保持不变有效T'是协变的。
我想知道这是否是因为
IList
不支持方差?@IronicMuffin当然,您的方差仍然需要有效。这就是为什么我说这是一种可能性,而不是保证;p我不是100%确定,因为我现在没有时间详细研究它,但问题可能是肯定的。为了使用
out
,“从类返回一个类型(例如返回值),该类型应该是相同的类型,这意味着它也是该类型的任何基类型。”。该类型只能用作“输出”。更多的细节在我写的博客文章中,当然也在msdn文档中。谢谢,我会看一看。这东西很难升级。我目前的解决方法是使用单独的方法将对象从会话中拉出,然后使用大部分逻辑调用一个方法,该逻辑将接口作为参数。@IronicMuffin我知道一开始很难掌握,尤其是文档中使用的深奥术语。:)这就是我写这篇博文的原因,是为了亲自了解它,并以更人道的方式解释它。我的猜测是,你必须定义一个额外的接口,这个接口只能输出,然后你就可以使它逆变。。。(还是共同的?)。。。。出局:)列表不仅仅是因为您还可以向列表中添加元素……因为您的答案是错误的。“所以IHeader对象应该不会出现问题”我想我不确定。你是说,对于细节记录根本不使用接口?@IronicMuffin:我是说不要将
IDetail
声明为接口,但请看我关于
dynamic
的最新评论。噢,
dynamic
。我没想到。我仍然需要玩弄那个关键词。如果你能以某种方式将其融入到设计中,那么使用co和contraviance仍然是一条路要走。