C#的抽象结构 [英] C# abstract struct

查看:147
本文介绍了C#的抽象结构的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我怎样才能实现在C#中的继承结构(或类似)?
我知道,一个抽象的结构是不可能的,但我需要实现类似的东西。

How can I achieve inheritance (or similar) with structs in C#? I know that an abstract struct isn't possible, but I need to achieve something similar.

我需要它作为一个结构,因为它是一个值类型。我需要继承,因为我需要一个通用的阵列和方法,我可以garantee在那里。

I need it as a struct because it has to be a value type. And I need inheritance because I need a generic array and methods that I can garantee are there.

我想一个例子很长的路要走,因此,继承人赢得一些代码T编译,但显示我想要达到的目标;

I think an example will go a long way, so heres some code that won't compile, but shows what I want to achieve;

    abstract struct Vertex
    {
       abstract int SizeInBytes;
       abstract void SetPointers();
    }
    struct ColorVertex : Vertex
    {
       Vector3 Position;
       Vector4 Color;

       override int SizeInBytes //static
       {
          get { return (3 + 4) * 4; }
       }
       override void SetVertexPointers() //static
       {
           ...
       }
    }

class main
{
   static void main()
   {
      Vertex[] verts = new Vertex[3];
      for(int i = 0; i < 3; i++)
          verts[i] = new ColorVertex();

      verts[0].SetVertexPointers(); //should call ColorVertex.SetVertexPointers

      externalAPIcall(verts);
   }
}



编辑:

我需要的值类型的原因是,这样我可以让他们的数组,并将它传递给OpenGL作为顶点缓冲。为此,需要将数据直接包含在此数组中。

The reason I need value types is so that I can make an array of them, and pass it to OpenGL as a vertex buffer. For this, the data needs to be directly contained in this array.

我会感到惊讶,如果这是根本不可能实现的。

I'd be surprised if this were simply not possible to achieve.

推荐答案

在你最近编辑光:

我之所以需要的值类型是这样,我可以让他们的数组,并将它传递给OpenGL作为顶点缓冲。为此,需要将数据直接包含在此数组中

The reason I need value types is so that I can make an array of them, and pass it to OpenGL as a vertex buffer. For this, the data needs to be directly contained in this array.

这似乎是的真正的解决方案对你来说是封装。如果布局你的结构是由第三方API(这样就可以与非托管代码交互)决定的,那么你真的应该考虑包装在适当的类的API类型而不是试图与他们直接在代码交互。

It seems like the real solution for you is encapsulation. If the layout of your struct is dictated by a third-party API (so that you can interact with unmanaged code), then you should really consider wrapping the API types in appropriate classes rather than trying to interact with them directly in code.

有关一个,你说出这样的:

For one, you state this:

我需要它作为一个结构因为它是一个值类型。我需要继承,因为我需要一个通用的数组,我可以garantee是否有方法。

I need it as a struct because it has to be a value type. And I need inheritance because I need a generic array and methods that I can garantee are there.

这不会变成你期望的方式。正如其他人所指出的那样,定义一组常见的功能,可以应用到结构的唯一途径是通过接口(例如,原始类型在.NET中实施 IComparable的) 。不幸的是,如果你要声明类型的数组 IYourInterface ,所有的值将得到盒装(接口引用是引用类型,即使他们指向的潜在价值。是值类型)

This won't turn out the way you're expecting. As others have pointed out, the only way to define a set of common functionality that can apply to structs is through interfaces (for example, the primitive types in .NET implement IComparable). Unfortunately, if you were to declare an array of type IYourInterface, all of the values will get boxed (interface references are reference types, even if the underlying value they're pointing to are value types).

例如,假设您声明 IVertex 接口:

For example, let's say you declare an IVertex interface:

public interface IVertex
{
    int SizeInBytes { get; }
    void SetPointers();
}

和你有一个或实现它更多的价值类型:

And you have one or more value types that implement it:

struct ColorVertex : IVertex
{
   Vector3 Position;
   Vector4 Color;

   override int SizeInBytes //static
   {
      get { return (3 + 4) * 4; }
   }
   override void SetVertexPointers() //static
   {
       ...
   }
}

当你做到这一点:

ColorVertex myVertex = new ColorVertex();

IVertex foo = myVertex;



第二行将框 myVertex 和存储在来的装箱值的引用。因为数组仅仅是一系列的变数,同样的规则:

The second line will box the value of myVertex and store a reference to that boxed value in foo. Since arrays are just a series of variables, the same rules apply:

IVertex[] foos = { myVertex };

所有值的 FOOS 将盒装,并存储它们的引用。这是不同于如果你这样做:

All of the values in foos will be boxed, and their references stored. This is different than if you did:

ColorVertex[] colors = { myVertex };



如果没有拳击是必要的。

Where no boxing is necessary.

这直接关系到你正在寻找什么,拳击比赛中值现在意味着你不再有值的连续块(​​当然,你这样做的影响,但是的连续的块只是引用;在值本身在其他地方)。

This has implications directly related to what you're seeking, as boxing the values now means that you no longer have a contiguous block of values (well, you do, but the contiguous block is just references; the values themselves lie elsewhere).

鉴于您


  1. 有一个定义类型第三方API,你需要使用

  2. 交互的需求,以支持不同的使用情况在代码,并希望使用面向对象的设计模式,这样做

您真的应该考虑包裹的OpenGL API。例如,假设你有以下内容:

You should really consider wrapping the OpenGL API. For example, let's say that you have the following:

// OpenGL type
struct Vertex
{
    int SizeInBytes;
}

public static extern void OpenGLFunction(Vertex[] vertices);



什么可能是一个更好的选择是定义你自己的接口,然后隐藏的OpenGL API:

What is likely a better option would be to define your own interface, then hide the OpenGL API:

public abstract class VertexBase
{
    internal Vertex ToVertex()
    {
        // your logic here
    }
}

public static class OpenGL
{
    public static void WrappedFunction(VertexBase[] vertices)
    {
        Vertex[] outVertices = new Vertex[vertices.Length];

        for(int i = 0; i < vertices.Length; i++)
        {
            outVertices[i] = vertices[i].ToVertex();
        }

        OpenGLFunction(outVertices);
    }
}



(这显然是一个人为的例子,但它应该演示一下我想在你的代码和其他API)

(This is obviously a contrived example, but it should demonstrate what I'm trying to get across in terms of introducing a layer of abstraction between your code and the other API)

这篇关于C#的抽象结构的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆