What I'm trying to achieve is say i have an array, i want to be able to modify a specific array element throughout my code, by pointing at it.
for example in C++ i can do this
int main(){
int arr [5]= {1,2,3,4,5};
int *c = &arr[3];
cout << arr[3] <<endl;
*c = 0;
cout << arr[3]<<endl;
}
I did some googling and there seems to be a way to do it through 'unsafe', but i don't really want to go that route.
I guess i could create a variable to store the indexes, but I'm actually dealing with slightly more complexity (a list within a list. so having two index variables seems to add complexity to the code.)
C# has a databinding class, so what I'm currently doing is binding the array element to a textbox (that i have hidden) and modifying that textbox whenever i want to modify the specific array element, but that's also not a good solution (since i have a textbox that's not being used for its intended purpose - a bit misleading).
A C# example of how you would like the use to look would help. If I understand what you're asking, a simple class like this might do it. What you're asking for though, doesn't seem like a very good idea. If you showed the larger scope in which you need this, someone might be able to point out a better design where you didn't need this sort of functionality at all.
public class ListElement<T> {
private IList<T> list;
private int index;
public ListElement(IList<T> list, int index) {
this.list = list;
this.index = index;
}
public T Value {
get {
return list[index];
}
set {
list[index] = value;
}
}
}
a use of this would look like
int[] arr = new int[] {1,2,3,4,5};
ListElement<int> third = new ListElement<int>(arr, 2);
Console.WriteLine(third.Value);
third.Value = 0;
Console.WriteLine(third.Value);
i'm not sure if this fits exactly, but the problem is that these pointers are not possible in c#.
if you have more complicated lists, you can take a look at LinkedList<T>
it provides a performant way if you want to change elements within a list.
I came up with a somewhat solution in C#. Granted this is off the cuff, so it may not work in all situations but I did test it briefly on your situation.
class Wrapper<T>
{
private T[] array;
private T item;
private int index;
public T Item { get { return item; } set { item = value;
array[Index] = value;
} }
public int Index
{
get { return index; }
set
{
index = value;
Item = array[value];
}
}
public Wrapper(T[] arr)
{
array = arr;
}
}
You can then use the class like this:
class Program
{
static void Main(string[] args)
{
int[] i = {1, 2, 3, 4, 5};
i.ToList().ForEach(x => Console.WriteLine(x));
Wrapper<int> w = new Wrapper<int>(i);
w.Index = 2;
w.Item = 5;
i.ToList().ForEach(x => Console.WriteLine(x));
Console.ReadLine();
}
}
This will give the output: 1234512545
It isn't as pretty as the solution in C++ but it will work as you want and provides a more "automatic" version of referencing the array.
I would wrap your arrays in Objects. In C#, stuff that needs pointer manipulation is usually best done with objects.
The advantage is that objects allow clearer naming and access to more complex data structures. You are right, it is not ideal to pass around sets of indices - the ordering and indexing is easily jumbled.. In fact, I think it was people in your position who decided Object-oriented programming would be a good idea!!
So you have class MyArray { }, and can use the 'object reference' as you would a pointer,
plus you can create arrays of MyArray[].
Related
I have a c# class that looks like this:
public class MemberData
{
public int meme_ck;
public string meme_name;
public bool meme_active;
public MemberData(int ck2, string name2, bool active2)
{
meme_ck = ck2;
meme_name = name2;
meme_active = active2;
}
}
I have made two arrays out of that class:
private MemberData[] memarray1 = new MemberData[10000];
private MemberData[] memarray2 = new Memberdata[10000];
Over the course of my application I do a bunch of stuff with these two arrays and values change, etc. Member's name or active status may change which results in the ararys becoming different.
Eventually I need to compare them in order to do things to the other one based on what results are kicked out in the first one.
For example, member is de-activated in the first array based on something application does, I need to update array 2 to de-activate that same member.
I am trying to use some database design philosphy with the int CK (contrived-key) to be able to rapidly look up the entry in the other array based on the CK.
Since I can't figure it out I've had to resort to using nested for loops like this, which sucks:
foreach (Memberdata md in memarray1)
{
foreach (Memberdatamd2 in memarray2)
{
if (md.ck = md2.ck)
{
//de-activate member
}
}
}
Is there a better way to do this? I just want to find the index in the second array based on CK when I have the CK value from the first array.
Any other tips or advice you have about structure would be appreciated as well. Should I be using something other than arrays? How would I accomplish this same thing with Lists?
Thanks!
Should I be using something other than arrays?
Yes. Don't use arrays; they are seldom the right data structure to use.
How would I accomplish this same thing with Lists?
Lists are only marginally better. They don't support an efficient lookup-by-key operation which is what you need.
It sounds like what you want is instead of two arrays, two Dictionary<int, MemberData> where the key is the ck.
I totally agree with Eric Lippert's answer above. It is better you do not use Array.
Same thing can be achieved using List<MemberData>. You can use LINQ as well to query your DataStructure.
Following is one of the way just to achieve your result using array
class Program
{
static MemberData[] memarray1 = new MemberData[10000];
static MemberData[] memarray2 = new MemberData[10000];
static void Main(string[] args)
{
for (int i = 0; i < memarray1.Length; i++)
{
memarray1[i] = new MemberData(i + 1, "MemName" + i + 1, true);
memarray2[i] = new MemberData(i + 1, "MemName" + i + 1, true);
}
// SIMULATING YOUR APP OPERATION OF CHANGING A RANDOM ARRAY VALUE IN memarray1
int tempIndex = new Random().Next(0, 9999);
memarray1[tempIndex].meme_name = "ChangedName";
memarray1[tempIndex].meme_active = false;
//FOR YOUR UDERSTADNING TAKING meme_ck IN AN INTEGER VARIABLE
int ck_in_mem1 = memarray1[tempIndex].meme_ck;
//FINDING ITEM IN ARRAY2
MemberData tempData = memarray2.Where(val => val.meme_ck == ck_in_mem1).FirstOrDefault();
// THIS IS YOUR ITEM.
Console.ReadLine();
}
}
I'm porting a C++ application to C# and experiencing some issues with pointers.
What I'm trying to achieve is to pass an array pointer with an offset so the passed function can work on the correct part of an array. I don't want to change the function's signature to add an extra value for the offset.
So, this is an example piece of C++ code I would like to pass in C#:
void DoSomething( double p[] )
{
p[0] = 0.4;
p[1] = 0.4;
}
int main()
{
double Vector[3];
Vector[0] = 0.2;
Vector[1] = 0.2;
Vector[2] = 0.2;
DoSomething( &Vector[1] );
}
How could I do that ? Keeping in mind that I can't pass the offset ?
[Edit]
Thank you all for the answers.
First, I have to apologize: I made a big mistake while copying the code.
I wrote
DoSomething( Vector[1] );
on last line instead of
DoSomething( &Vector[1] );
this has been corrected.
I then realized that I was not very clear about the signature.
I can slightly change the signature of the function, but I can't add any arguments
I am already using the "unsafe" and "fixed" keywords, so it won't hurt me
It doesn't need to be efficient code since this porting is intended to be a Quick & Dirty implementation of an algorithm written by somebody else for a prototype project. If the project is a "Ok go", the code would be thrown at garbage and rewritten in a C++ dll.
The function "DoSomething" is actually a nest of a few other functions, it is designed as a fast math work but sadly, I don't have all the knowledge about to code it myself. That's why I assume the author has nicely designed its function since it's used world-wide.
I'll try with Servy's suggestion and come back to you in a few days when I'll get back.
It's impossible to do without changing the signature of DoSomething at all, but you can avoid needing to pass along both an array and it's offset side by side all over the place. You can do that by creating a class that composes an array and also keeps track of an offset:
public class ArrayReference<T> : IEnumerable<T>
{
//you can keep these entirely private if you prefer
public T[] Array { get; private set; }
public int Offset { get; private set; }
public ArrayReference(T[] array, int offset)
{
Array = array;
Offset = offset;
}
public T this[int index]
{
get
{
return Array[index + Offset];
}
set
{
Array[index + Offset] = value;
}
}
public int Length
{
get
{
return Array.Length - Offset;
}
}
public IEnumerator<T> GetEnumerator()
{
for (int i = Offset; i < Array.Length; i++)
yield return Array[i];
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
public static ArrayReference<T> operator +(
ArrayReference<T> reference, int offset)
{
return new ArrayReference<T>(reference.Array, reference.Offset + offset);
}
public static ArrayReference<T> operator -(
ArrayReference<T> reference, int offset)
{
return new ArrayReference<T>(reference.Array, reference.Offset - offset);
}
public static implicit operator ArrayReference<T>(T[] array)
{
return new ArrayReference<T>(array, 0);
}
public static implicit operator T[](ArrayReference<T> reference)
{
return reference.ToArray();
}
}
You may want to add additional functionality to this, based on your specific needs. You can expose as much or as little of the underlying array's functionality as you need/want.
This is actually not the way you would do it in C#.
The only way to do this is to use unsafe code, and even then it wouldn't be a good implementation, because your method would be unsafe, and your array must be fixed.
The fixed keyword would prevent your array to be moved in another place in memory by the garbage collector, but it could lead to partitioned memory and then worse performance.
Moreover, even by design this isn't a good thing, because you don't know your array boundaries in your method.
But if you really want to do this, go with the enumerators.
In your main method:
double[] d = new double[3];
d[0] = 1.0;
d[1] = 2.0;
d[2] = 3.0;
IEnumerator<double> e = d.AsEnumerable().GetEnumerator();
e.MoveNext();
tryEnumerate(e);
and then your DoSomething method:
static void DoSomething(IEnumerator<double> e)
{
while(e.MoveNext())
Console.WriteLine(e.Current.ToString());
}
Code updated to show chaining using extension methodology. You can easly return any and all changes and update anything wanted.
List<double> Vector;
Vector.Add(0.2);
Vector.Add(0.2);
Vector.Add(0.2);
DoSomething(Vector.GetRange(index,count));
If you need to maintain the original list do this:
public static List<double> GetRange(static List<double> list, int index, int count){
return list.GetRange(Index,Count);
}
public static List<double> DoSomething(static List<double> list){
//do something here
}
Use it like this:
OriginalList().GetRange(Index,Count).DoSomething();
I'm creating a C# class with array members that is supposed to work like a List.
I want something syntax that is similar to the following when adding a book to a book list.
book.Add(firstName = "Jack", lastName = "Reacher", title = "Dollar", year = 2005);
This book should now be added to an array.We keep track of all the books that we add to that array.
I also want to be able to write something like:
book.delete[2];
to delete the 3'rd book in from the array.
What would be the best way to accomplish this ?
From the perspective of OOP, a better way would just be to use the Generic List as pointed out by Shahrooz Jefri - and make a custom class or struct "Book", which would have member fields "string firstName", "string lastName", "string title", and "int year."
Then, juust make a list of books like this,
List<Book> books = new List<Book>();
books.Add(new Book("Jack","Reacher","Dollar",2005));
If you need to implement your own generic collection w/ static arrays, you can do something like:
public class MyList<T> {
private T[] internalArray;
private int capacity;
private int size;
public int Size { get { return size; } }
public MyList(){
this.size = 0;
this.capacity = 2; //put something you feel like is reasonable for initial capacity
internalArray = new T[2];
}
public void Add(T item){
int factor = 2; //some "growth" factor
if(this.size == this.capacity){
this.capacity *= factor;
T[] newArray = new T[this.capacity];
System.Array.Copy(this.internalArray, newArray, this.size);
this.internalArray = newArray;
}
this.internalArray[this.size] = item;
this.size ++;
}
public void RemoveAt(int index){
//write code that shifts all elements following index back by one
//decrement the size
//if necessary for mem. conservation, shrink the array capacity if half of less elements remain
}
}
Off course, then you'll have to overload the [] bracket operator for access, perhaps make it implement the Enumerable, etc.
You can use Linq to object and for collecrion use Generic List
List<int> list = new List<int>();
list.Add(2);
list.Add(3);
list.Add(5);
list.Add(7);
If you want to add and remove items at will, then an array might not be the best choice. Resizing arrays is relatively expensive; it is better to use something like a list (as suggested by Shahrooz Jefri).
Also, I would shift the add/remove operation away from the book itself and towards the collection. Better to do:
bookList.Add(...)
...than...
book.Add(...)
typedef struct {
int e1;
int e2;
int e3;
int e4;
int e5;
} abc;
void Hello(abc * a, int index)
{
int * post = (&(a->e1) + index);
int i;
for(i = 0; i<5; i++)
{
*(post + i) = i;
}
}
The problem I face here is how they able to access the next element in the struct by
*(post + i)
I'm not sure how all these would be done in C# and moreover, I don't want to use unsafe pointers in C#, but something alternate to it.
Thanks!
You should replace the struct with an array of 5 elements.
If you want to, you can wrap the array in a class with five properties.
edit...
When you say 'Wrap,' it generally means to write properties in a class that set or get the value of either a single variable, an array element, or a member of another class whose instance lives inside your class (the usual usage here = 'wrap an object'). Very useful for separating concerns and joining functionality of multiple objects. Technically, all simple properties just 'wrap' their private member variables.
Sample per comment:
class test
{
int[] e = new int[5];
public void Hello(int index)
{
for (int i = 0; i <= 4; i++) {
// will always happen if index != 0
if (i + index > 4) {
MsgBox("Original code would have overwritten memory. .Net will now blow up.");
}
e[i + index] = i;
}
}
public int e1 {
get { return e[0]; }
set { e[0] = value; }
}
public int e2 {
get { return e[1]; }
set { e[1] = value; }
}
//' ETC etc etc with e3-e5 ...
}
The problem with the C code is that if index is greater than 0 it runs off the end of the abc struct, thus overwriting random memory. This is exactly why C#, a safer language, does not allow these sorts of things. The way I'd implement your code in C# would be:
struct abc
{
public int[] e;
}
void Hello(ref abc a, int index)
{
a.e = new int[5];
for (int i = 0; i < 5; ++i)
a.e[index + i] = i;
}
Note that if index > 0, you'll get an out of bounds exception instead of possibly silent memory overwriting as you would in the C snippet.
The thinking behind the C codes is an ill fit for C#. The C code is based on the assumption that the fields of the struct will be placed sequentially in memory in the order defined the fields are defined in.
The above looks like either homework or a contrived example. Without knowing the real intent it's hard to give a concrete example in C#.
other examples here suggest changing the data structure but if you can't/don't want to do that, you can use reflection combined with an array of objects of the struct type to accomplish the same result as above.
void Hello(abc currentObj){
var fields = typeof(abc).GetFields();
for(var i = 0;i<fields.Length;i++){
fields[i].SetValue(currentObj,i);
}
}
Today I've gone through what indexers are, but I am bit confused. Is there really a need for indexers? What are the advantages of using an indexer..... thanks in advance
I guess the simplest answer is to look at how you'd use (say) List<T> otherwise. Would you rather write:
string foo = list[10];
or
string foo = list.Get(10);
Likewise for dictionaries, would you rather use:
map["foo"] = "bar";
or
map.Put("foo", "bar");
?
Just like properties, there's no real need for them compared with just named methods following a convention... but they make code easier to understand, in my view - and that's one of the most important things a feature can do.
Indexers let you get a reference to an object in a collection without having to traverse the whole collections.
Say you have several thousands of objects, and you need the one before last. Instead of iterating over all of the items in the collection, you simply use the index of the object you want.
Indexers do no have to be integers, so you can use a string, for example, (though you can use any object, so long as the collection supports it) as an indexer - this lets you "name" objects in a collection for later retrieval, also quite useful.
I think zedo got closest to the real reason IMHO that they have added this feature. It's for convenience in the same way that we have properties.
The code is easer to type and easier to read, with a simple abstraction to help you understand.
For instance:
string[] array;
string value = array[0];
List<string> list;
string value = list[0]; //Abstracts the list lookup to a call similar to array.
Dictionary<string, int> map;
int value = map["KeyName"]; //Overloaded with string lookup.
Indexers allow you to reference your class in the same way as an array which is useful when creating a collection class, but giving a class array-like behavior can be useful in other situations as well, such as when dealing with a large file or abstracting a set of finite resources.
yes , they are very use of
you can use indexers to get the indexed object.
Taken from MSDN
Indexers are most frequently implemented in types whose primary purpose is to encapsulate an internal collection or array.
Full Story
for some reason, use indexer can let you create meaningful index to store or map your data. then you can get it from other side by the meaningful index.
using System;
/* Here is a simple program. I think this will help you to understand */
namespace Indexers
{
class Demo
{
int[] a = new int[10];
public int Lengths
{
get
{
return a.Length;
}
}
public int this[int index]
{
get
{
return a[index];
}
set
{
a[index] = value;
}
}
}
class Program
{
static void Main(string[] args)
{
Demo d = new Demo(); // Notice here, this is a simple object
//but you can use this like an array
for (int i = 0; i < d.Lengths; i++)
{
d[i] = i;
}
for (int i = 0; i < d.Lengths; i++)
{
Console.WriteLine(d[i]);
}
Console.ReadKey();
}
}
}
/*Output:
0
1
2
3
4
5
6
7
8
9
*/