为什么需要石膏?

Why is a cast required?

提问人:jeancallisti 提问时间:5/27/2023 最后编辑:jeancallisti 更新时间:5/27/2023 访问量:88

问:

(.Net 6,c# 10)

看看这段代码:

public class A {
   int Foo { get; set; }    
}

public interface IResponse : IEnumerable<A> {}



public class Program
{
    public static void Main() {
        var asList = new List<A>();

        IEnumerable<A> asEnumerable = asList;

        IResponse asResource = asEnumerable;
    }
}

编译器在线抱怨:IResponse asResource = asEnumerable;

Cannot implicitly convert type 'System.Collections.Generic.IEnumerable<A>' to 'IResponse'. 
An explicit conversion exists (are you missing a cast?)

有没有一种“干净”的方法来解决这个问题?大多数时候,露骨的演员表被用作最后的手段,我担心我错过了什么。

编辑:是因为“IResource : IEnumerable”语法告诉编译器 IResource 可能比 IEnumerable “更多”,因此在代码的后面尝试转换时,它不能保证 IResources 扩展的潜在其他接口“仅”存在于 IEnumerable 中?

也许我太习惯了 TypeScript,编译器会检查所有接口是否始终匹配。

编辑 2 :IResource 的原因或多或少是多个文件中返回类型的别名。我知道以下技巧:

using IResource = IEnumerable<A>;

但问题是我必须在每个文件中都这样做。如果您知道更好的解决方案...

C# 10.0

评论

6赞 mason 5/27/2023
仅仅因为 IResponse 实现了 IEnumerable<A>并不意味着 IEnumerable<A> 一定是 IResponse。
1赞 Pete 5/27/2023
您可以创建一个类 A 的成员函数,将自身转换为 IResponse?
3赞 mason 5/27/2023
例如,如果你有 ,你可以确定猫始终是动物。但你不能确定动物总是猫。动物的特定实例可能是猫,但它也可能是狗或大猩猩或任何其他实现或继承自 Animal 的类型。class Cat : Animal
0赞 jeancallisti 5/27/2023
@mason你是对的,我是通过与自己“橡皮鸭”来理解的。这是第一次编辑。你能看一下 EDIT 2 吗?
1赞 mason 5/27/2023
我不知道你想通过第二次编辑完成什么。但这不是询问它的合适地方。它与您的原始问题无关。

答:

0赞 Luke Vo 5/27/2023 #1

如果要为整个项目全局指定类型的别名,请使用带有全局修饰符的指令:using

// In any file, do this once
global using IResource = IEnumerable<A>;
global using B = System.Collections.Generic.List<int>;

然后在任何地方使用它:

IResource  a = new List<string>();

B b = new();
Console.WriteLine(b.GetType().Name); // prints List`1

评论

0赞 jeancallisti 5/27/2023
我很困惑,因为这不是我最初的问题,但是你正在回答我的第二个问题;如果我将您标记为“已接受的答案”,那么您将获得我应该给@mason的分数
0赞 Luke Vo 5/27/2023
@jeancallisti是的,下次要么关闭这个问题并创建另一个问题,要么在编辑时,也请编辑标题,如果问题以某种方式发生变化,请修改主要问题。
0赞 jeancallisti 5/27/2023
周一,我将重新发布我的第二个问题并让您知道,以便能够与您或其他人一起探索更多。现在,如果他发表评论作为答案,我将给@mason点。