似乎List对象不能存储在C#中的List变量中,甚至不能以这种方式显式转换.
List<string> sl = new List<string>();
List<object> ol;
ol = sl;
Run Code Online (Sandbox Code Playgroud)
结果无法隐式转换System.Collections.Generic.List<string>为System.Collections.Generic.List<object>
然后...
List<string> sl = new List<string>();
List<object> ol;
ol = (List<object>)sl;
Run Code Online (Sandbox Code Playgroud)
结果无法将类型转换System.Collections.Generic.List<string>为System.Collections.Generic.List<object>
当然,您可以通过从字符串列表中提取所有内容并将其一次放回一个来实现,但这是一个相当复杂的解决方案.
我正在学习C#泛型并为测试目的制作一些虚拟代码.所以,我正在测试Generic Modifier,它指定type参数是逆变的.
鉴于以下界面:
public interface IInterfaceTest<in T>
{
void Method(T value);
void Method(IList<T> values);
void Method(IEnumerable<T> values);
}
Run Code Online (Sandbox Code Playgroud)
编译时,我收到错误消息:
[CS1961]无效方差:类型参数"T"必须在"IInterfaceTest.Method(IList)"上无效有效.'T'是逆变的.
该错误仅与该行相关void Method(IEnumerable<T> values).如果删除此行,则一切正常.
所以我的问题是:为什么我可以使用通用逆变IEnumerable而不使用IList?我忘记了什么吗?
谢谢.
我试图在C#中的泛型类型参数中使用多态.我已经在SO(审查其他几个问题1,2,3,4,5,6),但我仍然不清楚为什么这不工作(或者如果它甚至允许的).
我有以下课程:
public class Base { }
public class Derived<T> : Base { }
public class Foo { }
Run Code Online (Sandbox Code Playgroud)
和我的派生泛型类型的实例:
var derived = new Derived<Foo>();
Run Code Online (Sandbox Code Playgroud)
以下陈述都是正确的:
derived is Object
derived is Base
derived is Derived<Foo>
Run Code Online (Sandbox Code Playgroud)
当我尝试将我的派生类用作另一个泛型类型中的类型参数时,我得到一些意外的行为.鉴于以下惰性实例:
var lazy = new Lazy<Derived<Foo>>();
Run Code Online (Sandbox Code Playgroud)
以下是真实的:
lazy is Lazy<Derived<Foo>>
Run Code Online (Sandbox Code Playgroud)
但是当我预期它们是真的时,这些都是错误的:
lazy is Lazy<Object>
lazy is Lazy<Base>
Run Code Online (Sandbox Code Playgroud)
为什么是这样?它们应该是真的还是我误解了仿制药是如何工作的?
检查是否IEnumerable<T1>协变的常见规则是什么IEnumerable<T2>?
我做了一些实验:
1.
Object Obj = "Test string";
IEnumerable<Object> Objs = new String[100];
Run Code Online (Sandbox Code Playgroud)
因为IEnumerable<out T>协变和String继承而起作用Object.
2.
interface MyInterface{}
struct MyStruct:MyInterface{}
.....
Object V = new MyStruct();
Console.WriteLine(new MyStruct() is Object); // Output: True.
IEnumerable<Object> Vs = new MyStruct[100]; // Compilation error here
Run Code Online (Sandbox Code Playgroud)
MyStruct实际上是一个Object,但它不起作用,因为Object是引用类型,MyStruct是值类型.好的,我在这看到一些逻辑.
3.
Console.WriteLine(new MyStruct() is ValueType); // Output: "True"
ValueType V2 = new MyStruct();
IEnumerable<ValueType> Vs2 = new MyStruct[100]; // Compilation …Run Code Online (Sandbox Code Playgroud) 我有以下简短的C#程序:
IList<string> listString = new List<String>();
IList<object> listObject;
listObject = listString;
Run Code Online (Sandbox Code Playgroud)
这个程序不编译.最后一行导致以下编译错误:
无法将类型'System.Collections.Generic.IList'隐式转换为'System.Collections.Generic.IList'.存在显式转换(您是否错过了演员?)
所以,我添加了演员:
listObject = (IList<object>)listString;
Run Code Online (Sandbox Code Playgroud)
现在程序正确编译,但在运行时失败.的InvalidCastException升高与以下消息:
无法将类型为'System.Collections.Generic.List'1 [System.String]'的对象强制转换为'System.Collections.Generic.IList'1 [System.Object]'.
强制转换是非法的,应该被编译器捕获,或者它是合法的,不应该在运行时抛出异常.为什么行为不一致?
澄清:我不是在问为什么演员会失败.我明白为什么这样的铸造有问题.我问为什么演员阵容只在运行时失败.
我正在尝试学习如何使用c#创建泛型类.有人可以解释为什么我运行这个程序时出现编译错误.
我创建了IZooAnimal接口.所有动物园动物都将实现此界面.
public interface IZooAnimal
{
string Id { get; set; }
}
public class Lion : IZooAnimal
{
string Id { get; set; }
}
public class Zebra : IZooAnimal
{
public string Id { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
ZooCage将容纳相同类型的动物
public class ZooCage<T> where T : IZooAnimal
{
public IList<T> Animals { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
动物园类有笼子
public class Zoo
{
public IList<ZooCage<IZooAnimal>> ZooCages { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
使用类的程序
class Program
{
static void Main(string[] args)
{
var …Run Code Online (Sandbox Code Playgroud) 给出以下LinqPad示例:
void Main()
{
List<DbItem> dbItems = new List<DbItem>
{
new DbItem{Id = 4, SomeValue = "Value For 4", OtherValue = 1},
new DbItem{Id = 19, SomeValue = "Value For 19", OtherValue = 2}
};
ListMethod(dbItems.Cast<IDbItem>().ToList()); <-+
EnumerableMethod(dbItems); <-+
} |
|
// These are the methods are I asking about -------+
public void ListMethod(List<IDbItem> dbItems)
{
Console.WriteLine(dbItems);
}
public void EnumerableMethod(IEnumerable<IDbItem> dbItems)
{
Console.WriteLine(dbItems);
}
public class DbItem : IDbItem
{
public int Id {get; set;}
public string SomeValue …Run Code Online (Sandbox Code Playgroud) 我有一个服务器端代码,我从数据库返回一个匿名类列表:
public ActionResult DisplayMap()
{
ViewBag.Checkins = (from locationUpdate in db.LocationUpdates
select new
{
locationUpdate,
locationUpdate.User
}).ToList();
return View();
}
Run Code Online (Sandbox Code Playgroud)
在Razor页面,我想得到这个列表的计数:
@if (ViewBag.Checkins.Count() > 0)
{ ... }
Run Code Online (Sandbox Code Playgroud)
但是,它会抛出一个错误:
An exception of type 'Microsoft.CSharp.RuntimeBinder.RuntimeBinderException' occurred
in System.Core.dll but was not handled in user code.
Additional information: 'object' does not contain a definition for 'Count'
Run Code Online (Sandbox Code Playgroud)
当我输入ViewBag.Checkins即时窗口时,我得到:
ViewBag.Checkins
{System.Collections.Generic.List<<>f__AnonymousType6<MY_APP.LocationUpdate,MY_APP.User>>}
[0]: { locationUpdate = {System.Data.Entity.DynamicProxies.LocationUpdate_4532566693B61EF657DDFF4186F1D6802EA1AC8D5267ED245EB95FEDC596E129}, User = {System.Data.Entity.DynamicProxies.User_816C8A417B45FE8609CD1F0076A5E6ECBAB0F309D83D2F8A7119044B1C6060CF} }
Run Code Online (Sandbox Code Playgroud)
该Checkins物体的确是List,数据是正确的.我试过Count,Length太(没有方法调用,就像属性),但没有运气.我究竟做错了什么?
简单的例子:
public class Person
{
String name;
}
public class VIP extends Person
{
String title;
}
Run Code Online (Sandbox Code Playgroud)
然后做:
public static void main(String[] args)
{
Person p = new Person();
p.name = "John";
VIP vip = new VIP();
vip.name = "Bob";
vip.title = "CEO";
List<Person> personList = new ArrayList<Person>();
List<VIP> vipList = new ArrayList<VIP>();
personList.add(p);
personList.add(vip);
vipList.add(vip);
printNames(personList);
printNames(vipList);
}
public static void printNames(List<Person> persons)
{
for (Person p : persons)
System.out.println(p.name);
}
Run Code Online (Sandbox Code Playgroud)
在"printNames(vipList)"上给出错误(必需的List <Person> found List <VIP>).
这是否意味着虽然VIP是Person,但List <VIP>不是List <Person>?
c# ×9
generics ×7
.net ×3
covariance ×2
asp.net-mvc ×1
ienumerable ×1
java ×1
polymorphism ×1
razor ×1
type-safety ×1