C# 4.0 无法将类型为X的对象强制转换为Y

C# 4.0 无法将类型为X的对象强制转换为Y,c#-4.0,interface,compiler-errors,runtime-error,C# 4.0,Interface,Compiler Errors,Runtime Error,我在一些代码中不断遇到异常“无法将X类型的对象强制转换为Y”。我有一个接口和两个实现它的类,当从一个转换到另一个时,它不断抛出这个错误。这两个类和接口位于同一程序集中的同一命名空间中,所以这不是问题所在。我创建了一个独立的控制台应用程序来解决这个问题,但我无法让它们相互转换。我想我忘记了一些基本的.Net规则。你觉得这代码有什么不对劲吗 我的独立应用程序代码: class Program { static void Main(string[] args) { R

我在一些代码中不断遇到异常“无法将X类型的对象强制转换为Y”。我有一个接口和两个实现它的类,当从一个转换到另一个时,它不断抛出这个错误。这两个类和接口位于同一程序集中的同一命名空间中,所以这不是问题所在。我创建了一个独立的控制台应用程序来解决这个问题,但我无法让它们相互转换。我想我忘记了一些基本的.Net规则。你觉得这代码有什么不对劲吗

我的独立应用程序代码:

class Program
{
    static void Main(string[] args)
    {

        RecurringPaymentResult r = new RecurringPaymentResult();
        r.AddError("test");
        ProcessPaymentResult p = null;
        p = (ProcessPaymentResult)r; // Doesn't compile. "Cannot convert type RecurringPaymentResult to ProcessPaymentResult"
        p = (IPaymentResult)r; // Doesn't compile. "Cannot convert type RecurringPaymentResult to ProcessPaymentResult. An explicit conversion exists (are you missing a cast?)"
        p = (ProcessPaymentResult)((IPaymentResult)r); // Compiles but throws: "Unable to cast object of type RecurringPaymentResult to ProcessPaymentResult" during runtime
    }
}
我的核心代码:

public interface IPaymentResult
{
    IList<string> Errors { get; set; }
    bool Success { get; }
    void AddError(string error);
}

public partial class RecurringPaymentResult : IPaymentResult
{
    public IList<string> Errors { get; set; }

    public RecurringPaymentResult() 
    {
        this.Errors = new List<string>();
    }

    public bool Success
    {
        get { return (this.Errors.Count == 0); }
    }

    public void AddError(string error) 
    {
        this.Errors.Add(error);
    }
}


public partial class ProcessPaymentResult : IPaymentResult
{
    private PaymentStatus _newPaymentStatus = PaymentStatus.Pending;
    public IList<string> Errors { get; set; }

    public ProcessPaymentResult() 
    {
        this.Errors = new List<string>();
    }

    public bool Success
    {
        get { return (this.Errors.Count == 0); }
    }

    public void AddError(string error)
    {
        this.Errors.Add(error);
    }

    // More properties and methods here…

}
公共接口IPaymentResult
{
IList错误{get;set;}
布尔成功{get;}
无效加法器(字符串错误);
}
公共部分类重复付款结果:IPaymentResult
{
公共IList错误{get;set;}
公共重复支付结果()
{
this.Errors=新列表();
}
公共事业的成功
{
获取{return(this.Errors.Count==0);}
}
公共无效加法器(字符串错误)
{
this.Errors.Add(error);
}
}
公共部分类ProcessPaymentResult:IPaymentResult
{
私有PaymentStatus _newPaymentStatus=PaymentStatus.Pending;
公共IList错误{get;set;}
公共进程PaymentResult()
{
this.Errors=新列表();
}
公共事业的成功
{
获取{return(this.Errors.Count==0);}
}
公共无效加法器(字符串错误)
{
this.Errors.Add(error);
}
//这里有更多的属性和方法…
}

我在您的代码中看到的一个主要错误是说“p=

您已经决定了p的类型,并且在该类型中分配了各种其他变量,这是错误的

以下是所有可能的转换:

RecurringPaymentResult r = new RecurringPaymentResult();
r.AddError("test");
ProcessPaymentResult p = null;

var r1 = (IPaymentResult)r;  //type of r1 becomes IPaymentResult
var r2 = (IPaymentResult)p;  //type of r2 becomes IPaymentResult
var r3 = (RecurringPaymentResult)r1; //type of r3 becomes RecurringPaymentResult 
var r4 =  (ProcessPaymentResult)r2; //type of r4 becomes ProcessPaymentResult
逻辑解释:

人(类)有眼(接口),象(类)有眼(接口)。接口提供了See方法()。人和鹿都通过使用See方法来实现眼睛界面


现在,您正在尝试将人对象转换为大象对象,这是不可能的,因为存储这些对象的空间有不同的要求。

RecurringPaymentResult
不是
ProcessPaymentResult
,它们的共同点就是该接口。除非在两者之间提供转换或调整层次结构,否则应该是这样的。好的,关闭以编写显式运算符。