patterncsharpMinor
Generics for reducing redundancies
Viewed 0 times
reducingredundanciesforgenerics
Problem
I have a routine that can be potentially reduced.
As you can see, there are two
The class
```
public T this[uint index]
{
get
{
if ((MemoryBuffer == null) || (MemoryBuffer.AlignedBuffer == IntPtr.Zero))
throw new InvalidOperationException("not defined");
if (index >= ItemCount)
throw new ArgumentException("index out of bounds", "index");
return ((T) Marshal.PtrToStructure(new IntPtr(MemoryBuffer.AlignedBuffer.ToInt64() + (index * mIte
internal ArrayBufferObject GetAccessorArray()
{
ColladaDocument colladaDocument = GetColladaDocument();
ColladaArray colladaArray = colladaDocument.GetSpecialElement(Source);
ArrayBufferObject bufferObject;
if (IsSimpleParamsConfiguration() == false)
throw new NotSupportedException("complex accessor params not supported");
string simpleParamsType = Params[0].Type;
if (simpleParamsType == ArrayTypeFloat) {
uint cursorOffset = Offset;
ArrayBufferObject arrayBufferObject = new ArrayBufferObject(BufferObject.Hint.StaticCpuDraw);
for (uint i = 0; i arrayBufferObject = new ArrayBufferObject(BufferObject.Hint.StaticCpuDraw);
for (uint i = 0; i < Count; i++) {
foreach (ColladaParam param in Params) {
if (param.Name != null)
arrayBufferObject[cursorOffset - Offset] = (int) colladaArray[cursorOffset];
cursorOffset++;
}
cursorOffset += Stride - (uint)Params.Count;
}
bufferObject = arrayBufferObject;
} else
throw new NotSupportedException(String.Format("simple accessor params type {0} not supported", simpleParamsType));
return (bufferObject);
}As you can see, there are two
if branches that are the same. Essentially they create a generic class using float and int type.The class
ArrayBufferObject is the base of ArrayBufferObject, but only the latter implements an indexer (strongly typed). It is implemented as following:```
public T this[uint index]
{
get
{
if ((MemoryBuffer == null) || (MemoryBuffer.AlignedBuffer == IntPtr.Zero))
throw new InvalidOperationException("not defined");
if (index >= ItemCount)
throw new ArgumentException("index out of bounds", "index");
return ((T) Marshal.PtrToStructure(new IntPtr(MemoryBuffer.AlignedBuffer.ToInt64() + (index * mIte
Solution
Presumably you could pull those sections out into a generic method.
And then replace those sections with a call to that method.
Depending on the types that you're converting to and from, the call to
private ArrayBufferObject CreateArrayBuffer(ColladaArray colladaArray)
{
uint cursorOffset = Offset;
ArrayBufferObject arrayBufferObject = new ArrayBufferObject(BufferObject.Hint.StaticCpuDraw);
for (uint i = 0; i < Count; i++)
{
foreach (ColladaParam param in Params)
{
if (param.Name != null)
arrayBufferObject[cursorOffset - Offset] = (T)Convert.ChangeType(colladaArray[cursorOffset], typeof(T));
cursorOffset++;
}
cursorOffset += Stride - (uint)Params.Count;
}
return arrayBufferObject;
}And then replace those sections with a call to that method.
if (simpleParamsType == ArrayTypeFloat)
return CreateArrayBuffer(colladaArray);
else if (simpleParamsType == ArrayTypeInt)
return CreateArrayBuffer(colladaArray);
else
throw new NotSupportedException(String.Format("simple accessor params type {0} not supported", simpleParamsType));Depending on the types that you're converting to and from, the call to
Convert.ChangeType() may have to be changed to something else, but it should be sufficient for the standard numeric types. For more information on type conversion, see this.Code Snippets
private ArrayBufferObject CreateArrayBuffer<T>(ColladaArray colladaArray)
{
uint cursorOffset = Offset;
ArrayBufferObject<T> arrayBufferObject = new ArrayBufferObject<T>(BufferObject.Hint.StaticCpuDraw);
for (uint i = 0; i < Count; i++)
{
foreach (ColladaParam param in Params)
{
if (param.Name != null)
arrayBufferObject[cursorOffset - Offset] = (T)Convert.ChangeType(colladaArray[cursorOffset], typeof(T));
cursorOffset++;
}
cursorOffset += Stride - (uint)Params.Count;
}
return arrayBufferObject;
}if (simpleParamsType == ArrayTypeFloat)
return CreateArrayBuffer<float>(colladaArray);
else if (simpleParamsType == ArrayTypeInt)
return CreateArrayBuffer<int>(colladaArray);
else
throw new NotSupportedException(String.Format("simple accessor params type {0} not supported", simpleParamsType));Context
StackExchange Code Review Q#8008, answer score: 4
Revisions (0)
No revisions yet.