拨开荷叶行,寻梦已然成。仙女莲花里,翩翩白鹭情。
IMG-LOGO
主页 文章列表 使用泛型进行界面向下转换

使用泛型进行界面向下转换

白鹭 - 2022-02-12 2099 0 0

我有以下代码,我想向下转换到具有泛型的界面,但出现运行时例外:无法将“FinalAssociator”型别的物件转换为“IAssociator`1[Common]”。

public interface ICommon 
{
    string Name {get;set;}
}
public class Common : ICommon 
{
    public string Name {get;set;}
}
public class FinalCommon : Common {}
public interface IAssociator<T> where T : ICommon
{
    void HandleEvent(T data);
}
public abstract class Associator<T> : IAssociator<T> where T : ICommon
{
    public abstract void HandleAnotherEvent(T data);
    public void HandleEvent(T data)
    {
        HandleAnotherEvent(data);
    }
}
public class FinalAssociator : Associator<FinalCommon>
{
    public override void HandleAnotherEvent(FinalCommon data)
    {
        Console.WriteLine(data.Name);
    }
}
var x = new FinalAssociator();
var y = new FinalCommon { Name = "John" };
var z = (IAssociator<Common>)x;
z.HandleEvent(y);

uj5u.com热心网友回复:

你不能这样做,因为它可能由于无效型别而导致运行时错误,这是泛型旨在防止的事情之一。考虑如果编译器允许您的代码会发生什么。你有:

z.HandleEvent(y);

y是 的一个实体FinalCommon,它不会出现问题。但是,如果您改为传入其他内容,例如:

z.HandleEvent(new Common());

这将导致您传递一个不FinalCommon属于您的方法的实体,而该实体肯定需要FinalCommon. 这是非法的,编译器会阻止您进入这种情况。

uj5u.com热心网友回复:

FinalAssociatior继承自Associator<FinalCommon>. 它的HandleAnotherEvent方法需要一个型别为 的自变量FinalCommon

如果您可以将它的实体转换为 asIAssociator<Common>那么您就可以将型别自变量传递Common给它,即使该类需要FinalCommon.

var finalAssociator = new FinalAssociator();
var commonAssociator = (IAssociator<Common>)finalAssociator; // can't do this

// You'd be able to do this because the interface allows it, but it doesn't
// make sense because the object is a FinalAssociator
// and it doesn't take this argument.
commonAssociator.HandleAnotherEvent(new Common()); 

正如所写,编译器无法确定这是无效的,这就是您收到运行时错误的原因。(Resharper 提供警告,这可能会在运行时失败。)

标签:

0 评论

发表评论

您的电子邮件地址不会被公开。 必填的字段已做标记 *