Is there a polymorphic 2D collection type that includes arrays in c#?
So let's say I have a helper class which contains methods that manipulate a collection:
public static void RemainingDegreeDistribution(IGraph graph, float[,] distArr)
{
int total = 0;
for(int i=0; i < graph.Edges.Count; i++)
{
int startRemDeg = graph.Edges[i].Start.RemDeg;
int endRemDeg = graph.Edges[i].End.RemDeg;
distArr[startRemDeg,endRemDeg]++;
distArr[endRemDeg, startRemDeg]++;
total = total+2;
}
for(int i=0; i < distArr.GetLength(0); i++)
{
for(int j=0; j < distArr.GetLength(1); j++)
{
distArr[i,j] /= total;
}
}
}
How can I change the code to allow the collection that is passed in to either be an array or one of my own collection classes?
The trouble is, the collection that is passed in must be 2-dimensional. There isn't an interface that I can implement in my own collection classes that arrays also implement.
I want to be able to reuse the code for both cases and avoid introducing lots of ugly conditional logic. I also need to avoid allocating memory so making some kind of wrapper class for arrays isn't acceptable. I also want to avoid using lists within lists as its so much simpler to work with normal 2d arrays and lists allocate too much memory for my purposes. It seems like this should be possible with indexers or something. Like is there a way to declare that "distArr" must be any type with an indexer that takes two arguments etc.?
c# arrays collections interface polymorphism
add a comment |
So let's say I have a helper class which contains methods that manipulate a collection:
public static void RemainingDegreeDistribution(IGraph graph, float[,] distArr)
{
int total = 0;
for(int i=0; i < graph.Edges.Count; i++)
{
int startRemDeg = graph.Edges[i].Start.RemDeg;
int endRemDeg = graph.Edges[i].End.RemDeg;
distArr[startRemDeg,endRemDeg]++;
distArr[endRemDeg, startRemDeg]++;
total = total+2;
}
for(int i=0; i < distArr.GetLength(0); i++)
{
for(int j=0; j < distArr.GetLength(1); j++)
{
distArr[i,j] /= total;
}
}
}
How can I change the code to allow the collection that is passed in to either be an array or one of my own collection classes?
The trouble is, the collection that is passed in must be 2-dimensional. There isn't an interface that I can implement in my own collection classes that arrays also implement.
I want to be able to reuse the code for both cases and avoid introducing lots of ugly conditional logic. I also need to avoid allocating memory so making some kind of wrapper class for arrays isn't acceptable. I also want to avoid using lists within lists as its so much simpler to work with normal 2d arrays and lists allocate too much memory for my purposes. It seems like this should be possible with indexers or something. Like is there a way to declare that "distArr" must be any type with an indexer that takes two arguments etc.?
c# arrays collections interface polymorphism
KeyValuePair<string, object[,]>
– jdweng
Jan 2 at 9:54
1
Sorry I don't quite understand how that is related.
– Jonathan
Jan 2 at 19:35
add a comment |
So let's say I have a helper class which contains methods that manipulate a collection:
public static void RemainingDegreeDistribution(IGraph graph, float[,] distArr)
{
int total = 0;
for(int i=0; i < graph.Edges.Count; i++)
{
int startRemDeg = graph.Edges[i].Start.RemDeg;
int endRemDeg = graph.Edges[i].End.RemDeg;
distArr[startRemDeg,endRemDeg]++;
distArr[endRemDeg, startRemDeg]++;
total = total+2;
}
for(int i=0; i < distArr.GetLength(0); i++)
{
for(int j=0; j < distArr.GetLength(1); j++)
{
distArr[i,j] /= total;
}
}
}
How can I change the code to allow the collection that is passed in to either be an array or one of my own collection classes?
The trouble is, the collection that is passed in must be 2-dimensional. There isn't an interface that I can implement in my own collection classes that arrays also implement.
I want to be able to reuse the code for both cases and avoid introducing lots of ugly conditional logic. I also need to avoid allocating memory so making some kind of wrapper class for arrays isn't acceptable. I also want to avoid using lists within lists as its so much simpler to work with normal 2d arrays and lists allocate too much memory for my purposes. It seems like this should be possible with indexers or something. Like is there a way to declare that "distArr" must be any type with an indexer that takes two arguments etc.?
c# arrays collections interface polymorphism
So let's say I have a helper class which contains methods that manipulate a collection:
public static void RemainingDegreeDistribution(IGraph graph, float[,] distArr)
{
int total = 0;
for(int i=0; i < graph.Edges.Count; i++)
{
int startRemDeg = graph.Edges[i].Start.RemDeg;
int endRemDeg = graph.Edges[i].End.RemDeg;
distArr[startRemDeg,endRemDeg]++;
distArr[endRemDeg, startRemDeg]++;
total = total+2;
}
for(int i=0; i < distArr.GetLength(0); i++)
{
for(int j=0; j < distArr.GetLength(1); j++)
{
distArr[i,j] /= total;
}
}
}
How can I change the code to allow the collection that is passed in to either be an array or one of my own collection classes?
The trouble is, the collection that is passed in must be 2-dimensional. There isn't an interface that I can implement in my own collection classes that arrays also implement.
I want to be able to reuse the code for both cases and avoid introducing lots of ugly conditional logic. I also need to avoid allocating memory so making some kind of wrapper class for arrays isn't acceptable. I also want to avoid using lists within lists as its so much simpler to work with normal 2d arrays and lists allocate too much memory for my purposes. It seems like this should be possible with indexers or something. Like is there a way to declare that "distArr" must be any type with an indexer that takes two arguments etc.?
c# arrays collections interface polymorphism
c# arrays collections interface polymorphism
edited Jan 2 at 19:34
Jonathan
asked Jan 2 at 9:46
JonathanJonathan
5343715
5343715
KeyValuePair<string, object[,]>
– jdweng
Jan 2 at 9:54
1
Sorry I don't quite understand how that is related.
– Jonathan
Jan 2 at 19:35
add a comment |
KeyValuePair<string, object[,]>
– jdweng
Jan 2 at 9:54
1
Sorry I don't quite understand how that is related.
– Jonathan
Jan 2 at 19:35
KeyValuePair<string, object[,]>
– jdweng
Jan 2 at 9:54
KeyValuePair<string, object[,]>
– jdweng
Jan 2 at 9:54
1
1
Sorry I don't quite understand how that is related.
– Jonathan
Jan 2 at 19:35
Sorry I don't quite understand how that is related.
– Jonathan
Jan 2 at 19:35
add a comment |
2 Answers
2
active
oldest
votes
There is no such interface. So you need to make your own, for instance:
public interface IMatrix<T>
{
int Rows { get; }
int Columns { get; }
ref T this[int row, int column] { get; }
}
and additionally of implementing it in your collection classes, create adapter for arrays (Adapter Pattern).
I know, I know, you said
I also need to avoid allocating memory so making some kind of wrapper class for arrays isn't acceptable.
I don't think a tiny short lived GC3 generation wrapper object will hurt your system, but anyway, the heap allocation can be avoided by implementing the wrapper as a struct
:
public struct ArrayMatrix<T> : IMatrix<T>
{
readonly T[,] source;
public ArrayMatrix(T[,] source) => this.source = source;
public int Rows => source.GetLength(0);
public int Columns => source.GetLength(1);
public ref T this[int row, int column] => ref source[row, column];
}
and making your method generic (to avoid boxing of the struct
):
public static void RemainingDegreeDistribution<TMatrix>(IGraph graph, TMatrix distArr)
where TMatrix : IMatrix<float>
{
int total = 0;
for (int i = 0; i < graph.Edges.Count; i++)
{
int startRemDeg = graph.Edges[i].Start.RemDeg;
int endRemDeg = graph.Edges[i].End.RemDeg;
distArr[startRemDeg, endRemDeg]++;
distArr[endRemDeg, startRemDeg]++;
total = total + 2;
}
for (int i = 0; i < distArr.Rows; i++)
{
for (int j = 0; j < distArr.Columns; j++)
{
distArr[i, j] /= total;
}
}
}
To make it easier to be used with arrays, you could add a helper method:
public static class ArrayMatrix
{
public static ArrayMatrix<T> ToMatrix<T>(this T[,] source) => new ArrayMatrix<T>(source);
}
and even provide overload of your method with array argument:
public static void RemainingDegreeDistribution(IGraph graph, float[,] distArr)
=> RemainingDegreeDistribution(graph, distArr.ToMatrix());
add a comment |
If you need to represent point in 2D space i suggesto you to use Point data structure.
https://docs.microsoft.com/en-us/dotnet/api/system.drawing.point?view=netframework-4.7.2
Try overloading if you also would pass an array of coordinates and points :
public static Method ( float[,] coordinates )
{
//generate array of Points starting from coordinates , points.Add ( new Point(coordinate[i,j]) )
}
public static Method ( Point points)
{
//actual logic
}
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54004138%2fis-there-a-polymorphic-2d-collection-type-that-includes-arrays-in-c%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
There is no such interface. So you need to make your own, for instance:
public interface IMatrix<T>
{
int Rows { get; }
int Columns { get; }
ref T this[int row, int column] { get; }
}
and additionally of implementing it in your collection classes, create adapter for arrays (Adapter Pattern).
I know, I know, you said
I also need to avoid allocating memory so making some kind of wrapper class for arrays isn't acceptable.
I don't think a tiny short lived GC3 generation wrapper object will hurt your system, but anyway, the heap allocation can be avoided by implementing the wrapper as a struct
:
public struct ArrayMatrix<T> : IMatrix<T>
{
readonly T[,] source;
public ArrayMatrix(T[,] source) => this.source = source;
public int Rows => source.GetLength(0);
public int Columns => source.GetLength(1);
public ref T this[int row, int column] => ref source[row, column];
}
and making your method generic (to avoid boxing of the struct
):
public static void RemainingDegreeDistribution<TMatrix>(IGraph graph, TMatrix distArr)
where TMatrix : IMatrix<float>
{
int total = 0;
for (int i = 0; i < graph.Edges.Count; i++)
{
int startRemDeg = graph.Edges[i].Start.RemDeg;
int endRemDeg = graph.Edges[i].End.RemDeg;
distArr[startRemDeg, endRemDeg]++;
distArr[endRemDeg, startRemDeg]++;
total = total + 2;
}
for (int i = 0; i < distArr.Rows; i++)
{
for (int j = 0; j < distArr.Columns; j++)
{
distArr[i, j] /= total;
}
}
}
To make it easier to be used with arrays, you could add a helper method:
public static class ArrayMatrix
{
public static ArrayMatrix<T> ToMatrix<T>(this T[,] source) => new ArrayMatrix<T>(source);
}
and even provide overload of your method with array argument:
public static void RemainingDegreeDistribution(IGraph graph, float[,] distArr)
=> RemainingDegreeDistribution(graph, distArr.ToMatrix());
add a comment |
There is no such interface. So you need to make your own, for instance:
public interface IMatrix<T>
{
int Rows { get; }
int Columns { get; }
ref T this[int row, int column] { get; }
}
and additionally of implementing it in your collection classes, create adapter for arrays (Adapter Pattern).
I know, I know, you said
I also need to avoid allocating memory so making some kind of wrapper class for arrays isn't acceptable.
I don't think a tiny short lived GC3 generation wrapper object will hurt your system, but anyway, the heap allocation can be avoided by implementing the wrapper as a struct
:
public struct ArrayMatrix<T> : IMatrix<T>
{
readonly T[,] source;
public ArrayMatrix(T[,] source) => this.source = source;
public int Rows => source.GetLength(0);
public int Columns => source.GetLength(1);
public ref T this[int row, int column] => ref source[row, column];
}
and making your method generic (to avoid boxing of the struct
):
public static void RemainingDegreeDistribution<TMatrix>(IGraph graph, TMatrix distArr)
where TMatrix : IMatrix<float>
{
int total = 0;
for (int i = 0; i < graph.Edges.Count; i++)
{
int startRemDeg = graph.Edges[i].Start.RemDeg;
int endRemDeg = graph.Edges[i].End.RemDeg;
distArr[startRemDeg, endRemDeg]++;
distArr[endRemDeg, startRemDeg]++;
total = total + 2;
}
for (int i = 0; i < distArr.Rows; i++)
{
for (int j = 0; j < distArr.Columns; j++)
{
distArr[i, j] /= total;
}
}
}
To make it easier to be used with arrays, you could add a helper method:
public static class ArrayMatrix
{
public static ArrayMatrix<T> ToMatrix<T>(this T[,] source) => new ArrayMatrix<T>(source);
}
and even provide overload of your method with array argument:
public static void RemainingDegreeDistribution(IGraph graph, float[,] distArr)
=> RemainingDegreeDistribution(graph, distArr.ToMatrix());
add a comment |
There is no such interface. So you need to make your own, for instance:
public interface IMatrix<T>
{
int Rows { get; }
int Columns { get; }
ref T this[int row, int column] { get; }
}
and additionally of implementing it in your collection classes, create adapter for arrays (Adapter Pattern).
I know, I know, you said
I also need to avoid allocating memory so making some kind of wrapper class for arrays isn't acceptable.
I don't think a tiny short lived GC3 generation wrapper object will hurt your system, but anyway, the heap allocation can be avoided by implementing the wrapper as a struct
:
public struct ArrayMatrix<T> : IMatrix<T>
{
readonly T[,] source;
public ArrayMatrix(T[,] source) => this.source = source;
public int Rows => source.GetLength(0);
public int Columns => source.GetLength(1);
public ref T this[int row, int column] => ref source[row, column];
}
and making your method generic (to avoid boxing of the struct
):
public static void RemainingDegreeDistribution<TMatrix>(IGraph graph, TMatrix distArr)
where TMatrix : IMatrix<float>
{
int total = 0;
for (int i = 0; i < graph.Edges.Count; i++)
{
int startRemDeg = graph.Edges[i].Start.RemDeg;
int endRemDeg = graph.Edges[i].End.RemDeg;
distArr[startRemDeg, endRemDeg]++;
distArr[endRemDeg, startRemDeg]++;
total = total + 2;
}
for (int i = 0; i < distArr.Rows; i++)
{
for (int j = 0; j < distArr.Columns; j++)
{
distArr[i, j] /= total;
}
}
}
To make it easier to be used with arrays, you could add a helper method:
public static class ArrayMatrix
{
public static ArrayMatrix<T> ToMatrix<T>(this T[,] source) => new ArrayMatrix<T>(source);
}
and even provide overload of your method with array argument:
public static void RemainingDegreeDistribution(IGraph graph, float[,] distArr)
=> RemainingDegreeDistribution(graph, distArr.ToMatrix());
There is no such interface. So you need to make your own, for instance:
public interface IMatrix<T>
{
int Rows { get; }
int Columns { get; }
ref T this[int row, int column] { get; }
}
and additionally of implementing it in your collection classes, create adapter for arrays (Adapter Pattern).
I know, I know, you said
I also need to avoid allocating memory so making some kind of wrapper class for arrays isn't acceptable.
I don't think a tiny short lived GC3 generation wrapper object will hurt your system, but anyway, the heap allocation can be avoided by implementing the wrapper as a struct
:
public struct ArrayMatrix<T> : IMatrix<T>
{
readonly T[,] source;
public ArrayMatrix(T[,] source) => this.source = source;
public int Rows => source.GetLength(0);
public int Columns => source.GetLength(1);
public ref T this[int row, int column] => ref source[row, column];
}
and making your method generic (to avoid boxing of the struct
):
public static void RemainingDegreeDistribution<TMatrix>(IGraph graph, TMatrix distArr)
where TMatrix : IMatrix<float>
{
int total = 0;
for (int i = 0; i < graph.Edges.Count; i++)
{
int startRemDeg = graph.Edges[i].Start.RemDeg;
int endRemDeg = graph.Edges[i].End.RemDeg;
distArr[startRemDeg, endRemDeg]++;
distArr[endRemDeg, startRemDeg]++;
total = total + 2;
}
for (int i = 0; i < distArr.Rows; i++)
{
for (int j = 0; j < distArr.Columns; j++)
{
distArr[i, j] /= total;
}
}
}
To make it easier to be used with arrays, you could add a helper method:
public static class ArrayMatrix
{
public static ArrayMatrix<T> ToMatrix<T>(this T[,] source) => new ArrayMatrix<T>(source);
}
and even provide overload of your method with array argument:
public static void RemainingDegreeDistribution(IGraph graph, float[,] distArr)
=> RemainingDegreeDistribution(graph, distArr.ToMatrix());
answered Jan 3 at 23:40
Ivan StoevIvan Stoev
108k788142
108k788142
add a comment |
add a comment |
If you need to represent point in 2D space i suggesto you to use Point data structure.
https://docs.microsoft.com/en-us/dotnet/api/system.drawing.point?view=netframework-4.7.2
Try overloading if you also would pass an array of coordinates and points :
public static Method ( float[,] coordinates )
{
//generate array of Points starting from coordinates , points.Add ( new Point(coordinate[i,j]) )
}
public static Method ( Point points)
{
//actual logic
}
add a comment |
If you need to represent point in 2D space i suggesto you to use Point data structure.
https://docs.microsoft.com/en-us/dotnet/api/system.drawing.point?view=netframework-4.7.2
Try overloading if you also would pass an array of coordinates and points :
public static Method ( float[,] coordinates )
{
//generate array of Points starting from coordinates , points.Add ( new Point(coordinate[i,j]) )
}
public static Method ( Point points)
{
//actual logic
}
add a comment |
If you need to represent point in 2D space i suggesto you to use Point data structure.
https://docs.microsoft.com/en-us/dotnet/api/system.drawing.point?view=netframework-4.7.2
Try overloading if you also would pass an array of coordinates and points :
public static Method ( float[,] coordinates )
{
//generate array of Points starting from coordinates , points.Add ( new Point(coordinate[i,j]) )
}
public static Method ( Point points)
{
//actual logic
}
If you need to represent point in 2D space i suggesto you to use Point data structure.
https://docs.microsoft.com/en-us/dotnet/api/system.drawing.point?view=netframework-4.7.2
Try overloading if you also would pass an array of coordinates and points :
public static Method ( float[,] coordinates )
{
//generate array of Points starting from coordinates , points.Add ( new Point(coordinate[i,j]) )
}
public static Method ( Point points)
{
//actual logic
}
answered Jan 2 at 10:29
SkarySkary
618726
618726
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54004138%2fis-there-a-polymorphic-2d-collection-type-that-includes-arrays-in-c%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
KeyValuePair<string, object[,]>
– jdweng
Jan 2 at 9:54
1
Sorry I don't quite understand how that is related.
– Jonathan
Jan 2 at 19:35