为什么这个C#代码示例没有工作?
我试图理解为什么这个转换不起作用:为什么这个C#代码示例没有工作?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace CastTest {
class Foo {}
// I want to use this kind of like a typedef, to avoid writing List<Foo> everywhere.
class FooList : List<Foo> {}
class Program {
static void Main(string[] args) {
FooList list = (FooList) Program.GetFooList();
}
// Suppose this is some library method, and i don't have control over the return type
static List<Foo> GetFooList() {
return new List<Foo>();
}
}
}
这会产生一个运行时错误:
InvalidCastException: Unable to cast object of type 'System.Collections.Generic.List`1[CastTest.Foo]' to type 'CastTest.FooList'.
任何人都可以解释为什么这不工作,以及是否我可以以某种方式解决这个问题?
您无法自动从父类转换为派生类:只是因为你正在试图投的对象是List<Foo>
并不一定使之成为FooList
。
退房:
你可以写一个List<Foo>
转换为FooList
操作,可能使用AddRange
填充值,如:
class FooList
{
public explicit operator FooList(List<Foo> arg)
{
FooList result = new FooList();
result.AddRange(arg);
return result;
}
}
此外,最好只使用一个using
别名: http://msdn.microsoft.com/en-us/library/sf0df423(v=vs.80).aspx
using FooList = List<Foo>;
这样你实际上并没有绕过不必要的派生类。
也许低调? – user1096188 2012-03-05 22:27:27
谢谢,使用'using'是一个很好的提示......我唯一的问题(以及我试图用类来解决它的原因)是'using'不能依赖于另一个' using'。与'using'需要使用完全限定的类型名称(即,您需要使用'System.Collections.Generic.List'而不是'List')和'using'声明相结合才能真正快速地实现真正的罗嗦。 – Eric 2012-03-05 22:45:11
只因为你的FooList是一个List不会使List成为FooList。
这种方法:
static List<Foo> GetFooList() {
return new List<Foo>();
}
...不返回FooList
。你的代码实际上是这样的:
FooList list = (FooList) new List<Foo>();
这根本不起作用。这是无效的:
string x = (string) new object();
你不会期望工作,你会吗?那么为什么你的FooList
版本工作?
最接近C#有一个typedef被称为使用别名指令:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace CastTest {
using FooList = List<Foo>;
class Foo {}
class Program {
static void Main(string[] args) {
FooList list = Program.GetFooList();
}
// Suppose this is some library method, and i don't have control over the return type
static List<Foo> GetFooList() {
return new List<Foo>();
}
}
}
你有什么创造了一个派生类FooList
,但是这创造了一个别名FooList
。它与List<Foo>
没有多少兼容,它是List<Foo>
。
既然你知道一个FooList
实际上是List<Foo>
的另一个名字,它可能看起来很奇怪。但考虑到FooList
本身可能包含成员,编译器不应该允许演员表演变得明显。想象一下你以后在FooList
上引入方法(Bar()
)。 List<Foo>
上不存在此方法,如果允许赋值(或强制转换),则类型系统会简单地中断。
因为不是所有的单子都是FooList。例如,我可以有:
public class AnotherFooList : List<Foo>
{
public object AdditionalPropery {get; set; }
}
它也从列表中继承,但不一样的FooList和FooList是不一样的,因为它。
你不能向上转型;但是您可以创建FooList的新实例及其内容
class Foo { }
// I want to use this kind of like a typedef, to avoid writing List<Foo> everywhere.
class FooList : List<Foo> {}
class Program
{
static void Main(string[] args)
{
FooList l = new FooList();
l.AddRange(GetFooList().Select(foo => foo));
Console.ReadLine();
}
// Suppose this is some library method, and i don't have control over the return type
static List<Foo> GetFooList()
{
return new List<Foo>();
}
}
哪一行产生错误? – ChrisF 2012-03-05 22:26:52
这是正确的说:FooList是列表,或列表是FooList? –
2012-03-05 22:29:43
@AnthonyPegram前者。 – hvd 2012-03-05 22:31:33