gpt4 book ai didi

c# - 将数组限制为特定类型 - 自定义纹理类 C#?

转载 作者:行者123 更新时间:2023-11-30 20:14:55 24 4
gpt4 key购买 nike

我正在尝试创建一个自定义纹理类,并且我希望能够选择纹理是 8 位还是浮点 a.k.a 我希望能够设置 _buffer要么是RGBFloat[]RGBByte[]但是我无法弄清楚如何在不使整个类通用的情况下做到这一点,但是如果我将其通用化,则可以设置其他对象类型,而不仅仅是我想将其限制为的对象类型。也许可以以某种方式使用继承或接口(interface),我不知道。

示例 C# 代码: (带 T 的地方不正确,只是占位符)

public struct RGBFloat
{
public float R { get; }
public float G { get; }
public float B { get; }

public RGBFloat(float r, float g, float b)
{
R = r;
G = g;
B = b;
}
}

public struct RGBByte
{
public byte R { get; }
public byte G { get; }
public byte B { get; }

public RGBByte(byte r, byte g, byte b)
{
R = r;
G = g;
B = b;
}
}

public enum TextureFormat
{
RGBFloat,
RGBByte
}

public class Texture2D
{
public int Width { get; }
public int Height { get; }
private T[] _buffer; // want it to be able to be either RGBFloat[] or RGBByte[] but nothing else.

public Texture2D(int width, int height, TextureFormat textureFormat)
{
Width = width;
Height = height;
switch (textureFormat)
{
case TextureFormat.RGBFloat:
_buffer = new RGBFloat[width * height];
break;
default:
_buffer = new RGBByte[width * height];
break;
}
}

public T this[int i]
{
get { return (_buffer[i]); }
set { _buffer[i] = value; }
}

public T this[int x, int y]
{
get { return (_buffer[Width * y + x]); }
set { _buffer[Width * y + x] = value; }
}
}

我创建的工作通用类示例,它类似于我的 TextureClass,但这个类旨在能够支持任何对象类型。

public class Computebuffer<T>
{
public int Count { get; }
private T[] _buffer;

public Computebuffer(int count)
{
Count = count;
_buffer = new T[count];
}

public T this[int i]
{
get { return (_buffer[i]); }
set { _buffer[i] = value; }
}

public void Initialize(T value)
{
for (int i = 0; i < Count; i++)
{
_buffer[i] = value;
}
}

public void SetData(T[] data)
{
for (int i = 0; i < data.Length; i++)
{
_buffer[i] = data[i];
}
}

public void GetData(T[] data)
{
for (int i = 0; i < data.Length; i++)
{
data[i] = _buffer[i];
}
}


public void Clear()
{
_buffer = new T[Count];
}
}

编辑 1:(更新版本,几乎可以工作):问题: 使用此代码,我可以将 RGBFloat 添加到 Texture2D,但这没有任何意义。 (查看主程序)

public interface IRGBType { }

public struct RGBFloat : IRGBType
{
public float R { get; }
public float G { get; }
public float B { get; }

public RGBFloat(float r, float g, float b)
{
R = r;
G = g;
B = b;
}
}

public struct RGBByte : IRGBType
{
public byte R { get; }
public byte G { get; }
public byte B { get; }

public RGBByte(byte r, byte g, byte b)
{
R = r;
G = g;
B = b;
}
}


public class Texture2D<T> where T : struct, IRGBType
{
public int Width { get; }
public int Height { get; }
private IRGBType[] _buffer;

public Texture2D(int width, int height)
{
Width = width;
Height = height;
_buffer = new IRGBType[width * height];
Initialize();
}

private void Initialize()
{
Type type = this.GetType();
if (type == typeof(RGBByte))
{
for (int i = 0; i < Width * Height; i++)
{
_buffer[i] = new RGBByte(0, 0, 0);
}
}
else
{
for (int i = 0; i < Width * Height; i++)
{
_buffer[i] = new RGBFloat(0, 0, 0);
}
}

}

public IRGBType this[int i]
{
get { return (_buffer[i]); }
set { _buffer[i] = value; }
}

public IRGBType this[int x, int y]
{
get { return (_buffer[Width * y + x]); }
set { _buffer[Width * y + x] = value; }
}
}

主程序:

Texture2D<RGBFloat> texFloat = new Texture2D<RGBFloat>(64, 64);
Texture2D<RGBByte> texByte = new Texture2D<RGBByte>(64, 64);
texFloat[32, 32] = new RGBFloat(10, 50, 60);
texByte[32, 32] = new RGBFloat(0.9f, 0.24f, 0.5f); // this should not work I should not be able to add a RGBFloat to a RGBByte Texture2D

编辑 2: (更新版本 v3) 仍然是一个问题,我将如何初始化 _buffer具有可选值的数组,非常新 Texture2D<RGBFloat>(64, 64)应该用 new RGBFloat(0,0,0) 初始化和 Texture2D<RGBFloat>(64, 64, new RGBFloat(0.5f,0.6f,0.7f))应该使用提供的值进行初始化:

public class Texture2D<T> where T : struct, IRGBType
{
public int Width { get; }
public int Height { get; }
private T[] _buffer;

public Texture2D(int width, int height, T? initializeValue = null)
{
Width = width;
Height = height;
_buffer = new T[width * height];
Initialize(initializeValue);
}

private void Initialize(T? value)
{
Type type = this.GetType();
T rgb;
if (type == typeof(RGBFloat))
{
rgb = value ?? new RGBFloat(0, 0, 0); // Error: Operator '??' cannot be applied to operands of type 'T' and 'RGBFloat'
}
else
{
rgb = value ?? new RGBByte(0, 0, 0); // Error: Operator '??' cannot be applied to operands of type 'T' and 'RGBByte'
}
for(int i = 0; i < Width*Height; i++)
{
_buffer[i] = rgb;
}
}

public T this[int i]
{
get { return (_buffer[i]); }
set { _buffer[i] = value; }
}

public T this[int x, int y]
{
get { return (_buffer[Width * y + x]); }
set { _buffer[Width * y + x] = value; }
}
}

编辑 3: 现在可以正常工作的完整最终版本:

public interface IRGBType { }

public struct RGBFloat : IRGBType
{
public float R { get; }
public float G { get; }
public float B { get; }

public RGBFloat(float r, float g, float b)
{
R = r;
G = g;
B = b;
}
}

public struct RGBByte : IRGBType
{
public byte R { get; }
public byte G { get; }
public byte B { get; }

public RGBByte(byte r, byte g, byte b)
{
R = r;
G = g;
B = b;
}
}

public class Texture2D<T> where T : struct, IRGBType
{
public int Width { get; }
public int Height { get; }
private T[] _buffer;

public Texture2D(int width, int height, T? initializeValue = null)
{
Width = width;
Height = height;
_buffer = new T[width * height];
if (initializeValue.HasValue)
{
for (int i = 0; i < Width * Height; i++)
{
_buffer[i] = initializeValue.Value;
}
};
}

public T this[int i]
{
get { return (_buffer[i]); }
set { _buffer[i] = value; }
}

public T this[int x, int y]
{
get { return (_buffer[Width * y + x]); }
set { _buffer[Width * y + x] = value; }
}
}

最佳答案

您可以创建一个您的RGBFloatRGBByte 结构实现的接口(interface),并将通用类型限制为该接口(interface)。界面可以只是一个“标记”,里面什么也没有:

public interface IRGBType { }

public struct RGBFloat : IRGBType
{
public float R { get; }
public float G { get; }
public float B { get; }

public RGBFloat(float r, float g, float b)
{
R = r;
G = g;
B = b;
}
}

public struct RGBByte : IRGBType
{
public byte R { get; }
public byte G { get; }
public byte B { get; }

public RGBByte(byte r, byte g, byte b)
{
R = r;
G = g;
B = b;
}
}

然后你可以让你的泛型类只接受实现这个接口(interface)的类型:

public class Texture2D<T> where T: IRGBType
{
...
}

如果您知道您将始终通过struct 实现此接口(interface),则可以进一步限制泛型:

public class Texture2D<T> where T: struct, IRGBType
{
...
}

编辑:确保在您的类中的任何地方都使用通用T 参数,而不是接口(interface)。这是确保类型安全所必需的,否则您的索引器可以接受任何 IRGBType,这可能会出现很大问题。正确用法:

public class Texture2D<T> where T: struct, IRGBType
{
private T[] _buffer;

public Texture2D(int width, int height)
{
...
_buffer = new T[width * height];
...
}

public T this[int i]
{
get => _buffer[i];
set => _buffer[i] = value;
}
}

关于c# - 将数组限制为特定类型 - 自定义纹理类 C#?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58036999/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com