我刚刚开始学习C#,我非常喜欢那里的列表概念。我只是想知道为什么我不能列出指针。我试图列出指向我班级对象的指针,但是当我写作时:
List <MyClass*> mylist;
甚至:
List <int*> mylist;
VS显示错误消息:
The type 'MyClass*" may not be used as a type argument
我不知道为什么。是否有任何解决方案或是否完全禁止制作指针类型列表?
(抱歉愚蠢的问题,我只是在学习东西)
答案 0 :(得分:1)
在C#中创建类实例列表比这更简单。您使用要存储的类或值初始化列表,然后添加实例或值。
例如,MyClass
个实例的列表将是这样的:
List<MyClass> myList = new List<MyClass>();
MyClass myClass1 = new MyClass;
myList.Add(myClass1);
或者对于int:
List<int> myList = new List<int>();
myList.Add(123);
就是这样。不需要指针来存储类的实例。
修改强>
C#中没有可能指向引用类型或包含引用的结构类型。这是因为即使指针指向它,垃圾收集器也可以收集引用类型。在MSDN Pointer types文章中更详细地描述了该主题。所以C#不允许MyClass*
之类的任何内容。
此外,在同一篇文章中,您可以发现唯一允许的指针类型是:sbyte,byte,short,ushort,int,uint,long,ulong,char,float,double,decimal或bool。
关于int*
List<int*>
作为from oauth2client.contrib.django_orm import CredentialsField
from oauth2client.contrib.django_orm import FlowField
from oauth2client.contrib.django_orm import Storage
the documentation中的类型参数的问题,指针类型不能用作类型参数。有关详细信息,请参见第18.4.1章。
答案 1 :(得分:1)
指针类型如int*
或甚至MyStruct*
(其中MyStruct
必须是具有通常布局的值类型,其实例字段(递归地)又是值类型)确实存在于C#中,但是在大多数应用程序中不经常使用。
但是,指针类型不能用作泛型类型参数,因此&#34; T
&#34; List<T>
中的int*
不允许int*[]
。可以使用指针数组,例如MyStruct*[]
或typeof(List<>).MakeGenericType(typeof(int*))
。
回答你的问题:不,没有办法为泛型类型参数使用指针类型。请注意,这不仅仅是C#限制,CLR类型系统拒绝它(例如object
会抛出异常)。
与此相关,指针类型不会从class
继承,例如&#34; normal&#34;具体类型在C#/ .NET类型系统中。
在C#中,指针只是值类型。使用引用类型(如用int*
声明的用户定义类型),&#34;值&#34;该类型的变量或表达式,是实际实例的 引用 (实现定义的内存位置),或 null引用 (不是指实例)。这些引用有点像&#34;指针&#34;,但它们不允许算术(如添加或减去内存位置,或将&#34;地址&#34;转换为整数)的方式类似{ {1}}和MyStruct*
做。
答案 2 :(得分:0)
如其他答案所述,您不能将指针类型用作通用参数。通常,只有在“不安全”部分中才允许使用C#中的指针,并且这些指针是不受管理的-您必须自己处理它们的创建和销毁。我的猜测是,泛型中不支持指针的原因是(a)它会与垃圾回收相混淆,并使其很容易被人用脚踩死,和/或(b)这不值得为之头痛语言设计师,因为指针在托管代码中应该很少见。
但是,在某些情况下,例如与传统C ++代码进行接口时,确实会出现很多情况。一种有用的解决方法是“ IntPtr”类。您已经注意到,它将无法编译:
MyClass* foo = ...;
List <MyClass*> mylist = new List<MyClass*>();
mylist.Add(foo);
MyClass* bar = mylist[0];
但是您应该能够通过将指针强制转换为IntPtr类型来做一个(丑陋的)解决方法:
MyClass* foo = ...;
List <IntPtr> mylist = new List<IntPtr>();
mylist.Add((IntPtr)foo);
MyClass* bar = (MyClass*)mylist[0];
但是同样,在纯托管代码中这样做通常不是明智的选择。通常,只有在必须与C ++代码进行互操作并且要跟踪一堆非托管结构时,我才会这样做。
答案 3 :(得分:0)
当我搜索“C# 指针列表”时出现了这个问题。就我而言,我想要一个 List<ulong*>
。这样的事情对我有用:
readonly unsafe struct ULongPointer
{
public readonly ulong* Value;
public ULongPointer(ulong* value)
{
Value = value;
}
}
ulong value = 0x123UL;
var listOfULongPointers = new List<ULongPointer>();
unsafe
{
listOfULongPointers.Add(new ULongPointer(&value));
*listOfULongPointers[0].Value = 0x321UL;
}
Assert.Equal(0x321UL, value);
请记住,当您拥有诸如 OP 的 MyClass
之类的引用类型时,您已经在处理引用了。因此,在这种情况下,您只需要一个 List<MyClass>
。