无法将源类型转换为目标类型

时间:2010-08-19 15:32:46

标签: c#

我有这个子类实现我的接口,并且在满足合同方面没有错误。但是,当我尝试在子类的构造函数中设置当前会话时,我尝试将变量类型与返回的GetCurrentSession()类型进行比较时得到此编译时错误:

“无法将源类型IAPISession转换为目标类型FacebookSession”

好吗? Facebook是IAPISession ......对吧?在我看来,多态性是我的想法所以应该对这种比较感到满意。在这里不确定。

public class FacebookSession : IAPISession
{
    private FacebookSession currentSession;

    private FacebookSession()
    {
        currentSession = GetCurrentSession();
    }

    ...more code

    public IAPISession GetCurrentSession()
    {
        // my logic is here...whatever that may be
    }
     ... more code
 }

更新

这是我的实际界面:

public interface IAPISession
{
    #region Properties

    int SessionID { get; }

    string UserID { get; }

    bool SessionHasExpired { get; }

    DateTime ExpirationDate { get; }

    void LogOut(); // expires the session & sets SessionHasExpired

    #endregion Properties

    #region Methods

    IAPISession GetCurrentSession();

    #endregion Methods

}

此接口将用于我们的任何API包装器项目(例如FlickrSession等)

5 个答案:

答案 0 :(得分:4)

是的,这需要一个明确的演员。您正在接收通用(接口)会话,但您想使用特定(Facebook)方法/字段。

可能设想GetCurrentSession()返回不同类型的IAPISession的方案!

  • 使用currentSession = (FacebookSession) GetCurrentSession();

  • 在演员周围使用try块 抓住这种可能性。我假设你的 如果不是,代码会感到困惑 一种FacebookSession,所以你 需要处理这种情况。

加成

只是为了澄清:

FacebookSession fbSess;
IAPISession     genSess;
FacebookSession getFbSession() { ... return this; }
IAPISession     getSession()   { ... return this; }

genSess = getSession();        // legal
genSess = getFbSession();      // legal - implicit cast works as FacebookSession 
                               // is always a kind of IAPISession
fbSess  = getFbSession();      // legal
fbSess  = getSession();        // ILLEGAL - not all IAPISession's will be
                               // kinds of FacebookSession
fbSess  = (FacebookSession) getSession();
                               // legal, but might throw a class cast exception
                               // if it isn't a FacebookSession.

同样,

genSess = fbSess;              // ok, implicit cast to generic type
fbSess  = genSess;             // ILLEGAL, it may not be a FacebookSession
fbSess  = (FacebookSession) genSess; 
                               // legal but can throw an exception

答案 1 :(得分:3)

虽然GetCurrentSession实际上可能返回FacebookSession,但返回类型为IAPISession,并且没有从接口到实现该接口的任何类的隐式强制转换。

GetCurrentSession方法的返回类型更改为FacebookSession或将currentSession字段类型更改为IAPISession(如果这样做有意义,则更改两者)。

答案 2 :(得分:1)

你需要反过来:

public class FacebookSession : IAPISession
{
    private IAPISession currentSession;

    private FacebookSession()
    {
        currentSession = GetCurrentSession();
    }

    ...more code

    public FacebookSession GetCurrentSession()
    {
        // my logic is here...whatever that may be
    }
     ... more code
 }

如果你想在类中使用特定的实现,那么我将在构造函数中实例化该类。然后在GetCurrentSession类中返回该实例。例如:

public class FacebookSession : IAPISession
{
    private FacebookSession currentSession;

    private FacebookSession()
    {
        currentSession = new FacebookSession();
    }

    ...more code

    public IAPISession GetCurrentSession()
    {
        return currentSession;
    }
     ... more code
 }

就像丹尼尔提到的那样,这已接近单身人士模式。查看它的实现here。请参阅.NET Optimized Code

下的部分

答案 3 :(得分:0)

在C#中,除非存在定义的强制转换,否则无法使用更通用的类型(在您的情况下为IAPISession)转换为更具体的类型(FacebookSession)而不使用显式强制转换

想想在这种情况下会发生什么:

var flickrSession = new FlickrSession();
var iApiFlickrSession = flickrSession as IAPISession;

var faceBookSession = iApiFlickrSession;

您可以保证FacebookSession的实例也是IAPISession的实例,但您不能总是保证IAPISession的实例也是FacebookSession的实例。

在第二种情况下,编译器不知道该怎么做。

您可以尝试使用as运算符(在您的情况下可能会或可能不会)。如果转换失败,该值将为null:

currentSession = GetCurrentSession() as FacebookSession;

答案 4 :(得分:0)

当你想要这样做时,你必须明确:

private FacebookSession() 
{ 
    currentSession = (FacebookSession) GetCurrentSession(); 
} 

请注意,GetCurrentSession()返回的对象的异常实际上不是FacebookSession

更新:

您似乎对运行时发生的事情与编译时发生的事情感到困惑:

    currentSession = GetCurrentSession(); 

这无法编译,因为虽然GetCurrentSession 返回的对象可能在运行时是FacebookSession对象,但所有编译器都知道它是实现IAPISession,可能有许多实现IAPISession的非FacebookSeesion对象。

    currentSession = (FacebookSession) GetCurrentSession(); 

在这里,您要告诉编译器,“相信我 - 当我们运行它时,它将成为一个FacebookSession对象。如果我要lyin',您可能会因为异常而崩溃!”

    currentSession = (int) GetCurrentSession(); 

这不会编译。你试图说“相信我”等等等,但是编译器称你的虚张声势说“Baloney!IAPISession无法成为int