C# C语言中的铸造问题#
我有一个程序C# C语言中的铸造问题#,c#,oop,C#,Oop,我有一个程序 using System; using System.Collections.Generic; namespace Generic { public class Program { public static void Main() { List<string> dd= Program.get(); } public static IList<string&
using System;
using System.Collections.Generic;
namespace Generic
{
public class Program
{
public static void Main()
{
List<string> dd= Program.get();
}
public static IList<string> get()
{
List<string> str = new List<string>();
return str;
}
}
}
使用系统;
使用System.Collections.Generic;
命名空间泛型
{
公共课程
{
公共静态void Main()
{
List dd=Program.get();
}
公共静态IList get()
{
List str=新列表();
返回str;
}
}
}
执行上述操作后,我得到:
无法隐式转换类型
'System.Collections.Generic.IList'
至'System.Collections.Generic.List'
。显式转换
存在
(你缺演员吗?)
因为,List,这应该不会失败。
那么为什么C#会抛出这个错误呢?虽然可以保证所有
List
对象都是IList
类型,但不能保证所有IList
对象都是List
类型,因为它可能是实现接口的一个完全不同的类。这意味着
List<string> dd= Program.get();
但是如果Program.get()
能够返回除List
之外的其他内容,这可能会导致运行时问题,而IList
恰好是在实现IList>时返回的
如果您确实需要访问仅在List
中可用的功能,那么最好将get()
的返回类型显式声明为List
,或者如果IList
接口提供了您想要调用的所有方法,则只将dd
的类型声明为IList
作为一个例子,考虑如下:
interface Foo {
public void doSomething();
}
class Bar : Foo {
public override void doSomething() {
Console.WriteLine("Hello World!");
}
}
class Baz : Foo {
public override void doSomething() {
Console.WriteLine("Goodbye World!");
}
}
class Program {
public static void Main(string[] args) {
Foo myFoo = getMyFoo();
myFoo.doSomething();
}
static Random random = new Random();
static Foo getMyFoo() {
if (random.NextDouble() < 0.5){
return new Bar();
}
else {
return new Baz();
}
}
}
接口Foo{
公共无效剂量();
}
酒吧类别:富{
公共覆盖无效doSomething(){
控制台。WriteLine(“你好,世界!”);
}
}
类别Baz:Foo{
公共重写void doSomething(){
控制台。WriteLine(“再见,世界!”);
}
}
班级计划{
公共静态void Main(字符串[]args){
Foo-myFoo=getMyFoo();
myFoo.doSomething();
}
静态随机=新随机();
静态Foo getMyFoo(){
if(random.NextDouble()<0.5){
返回新条();
}
否则{
返回新的Baz();
}
}
}
我们可以看到,Bar
和Baz
都属于Foo
类型,但我们永远无法保证从getMyFoo()
返回哪种类型,只是它属于Foo
类型。我们可以尝试显式地将myFoo
强制转换为一个或另一个,但在运行时通常会失败,因为Baz
不是Bar
类型,反之亦然。虽然您可以保证所有List
对象都是IList
类型,您不能保证所有的IList
对象都属于List
类型,因为它可能是实现接口的一个完全不同的类。这意味着
List<string> dd= Program.get();
但是如果Program.get()
能够返回除List
之外的其他内容,这可能会导致运行时问题,而IList
恰好是在实现IList>时返回的
如果您确实需要访问仅在List
中可用的功能,那么最好将get()
的返回类型显式声明为List
,或者如果IList
接口提供了您想要调用的所有方法,则只将dd
的类型声明为IList
作为一个例子,考虑如下:
interface Foo {
public void doSomething();
}
class Bar : Foo {
public override void doSomething() {
Console.WriteLine("Hello World!");
}
}
class Baz : Foo {
public override void doSomething() {
Console.WriteLine("Goodbye World!");
}
}
class Program {
public static void Main(string[] args) {
Foo myFoo = getMyFoo();
myFoo.doSomething();
}
static Random random = new Random();
static Foo getMyFoo() {
if (random.NextDouble() < 0.5){
return new Bar();
}
else {
return new Baz();
}
}
}
接口Foo{
公共无效剂量();
}
酒吧类别:富{
公共覆盖无效doSomething(){
控制台。WriteLine(“你好,世界!”);
}
}
类别Baz:Foo{
公共重写void doSomething(){
控制台。WriteLine(“再见,世界!”);
}
}
班级计划{
公共静态void Main(字符串[]args){
Foo-myFoo=getMyFoo();
myFoo.doSomething();
}
静态随机=新随机();
静态Foo getMyFoo(){
if(random.NextDouble()<0.5){
返回新条();
}
否则{
返回新的Baz();
}
}
}
我们可以看到,Bar
和Baz
都属于Foo
类型,但我们永远无法保证从getMyFoo()
返回哪种类型,只是它属于Foo
类型。我们可以尝试显式地将myFoo
强制转换为其中一个,但在运行时通常会失败,因为Baz
不是Bar
类型,反之亦然。List
是IList
的子类型,因此赋值无效。Thanls@Lee with logic List str=new List();也应该失败。但不是。这不是相同的逻辑,它失败的原因是相同的string s=new object()代码>无法编译。无法将某种类型的表达式分配给某个子类型的变量。List
是IList
的子类型,因此分配无效。Thanls@Lee with logic List str=new List();也应该失败。但不是。这不是相同的逻辑,它失败的原因是相同的string s=new object()代码>无法编译。您不能将某种类型的表达式赋给某个子类型的变量。谢谢@SAM的回答。谢谢@SAM的回答。