指针列表(指针类型)?

时间:2016-05-28 23:40:07

标签: c# list pointers types

我刚刚开始学习C#,我非常喜欢那里的列表概念。我只是想知道为什么我不能列出指针。我试图列出指向我班级对象的指针,但是当我写作时:

List <MyClass*> mylist;

甚至:

List <int*> mylist;

VS显示错误消息:

The type 'MyClass*" may not be used as a type argument

我不知道为什么。是否有任何解决方案或是否完全禁止制作指针类型列表?

(抱歉愚蠢的问题,我只是在学习东西)

4 个答案:

答案 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>