In C++, you could write the following code:
int Animal::*pAge= &Animal::age;
Animal a;
a.*pAge = 50;
Is there similar functionality in C#?
Edit: To clarify, I am not asking about pointers. I am asking about "pointers to members", a feature found in C++ that is used with the .* and ->* operators.
Edit 2: Here is an example of a use case for members to pointers.
Let's say we have the following class:
class Animal
{
int age;
int height;
int weight;
…
}
And let's say that we want to write methods that will find the average age/height/weight/etc. of all Animals in an array. We could then do this:
int averageAge(Animal[] animals)
{
double average = 0;
for (…)
average += animals[i].age;
return average/animals.length;
}
int averageHeight(Animal[] animals)
{
//code here again
}
int averageWeight(Animal[] animals)
{
//code here again
}
We would end up copying and pasting a lot of code here, and if our algorithm for finding the average changed, we would encounter a maintenance nightmare. Thus, we want an abstraction of this process for any member. Consider something like this:
int averageAttribute(Animal[] animals, Func<Animal, int> getter)
{
double average = 0;
for (…)
average += getter(animals[i]);
return average/animals.length;
}
which we could then call with
averageAttribute(animals, (animal) => animal.age);
or something similar. However, using delegates is slower than it has to be; we are using an entire function just to return the value at a certain location in the Animal struct. In C++, members to pointers allow you to do pointer math (not the right term but I can't think of a better term) on structs. Just as you can say
int p_fourthAnimal = 3;
(animals + p_fourthAnimal)*
to get the value so many bytes ahead of the pointer stored in the variable animals, in C++, you could say
int Animal::* p_age = &Animal::age;
animal.*p_age //(animal + [the appropriate offset])*
to get the value so many bytes ahead of the pointer stored in the variable animal; conceptually, the compiler will turn animal.*p_age into (animal + [the appropriate offset])*. Thus, we could declare our averageAttribute as this instead:
int averageAttribute(Animal[] animals, Animal::* member)
{
double average = 0;
for (…)
average += animals[i].*member; //(animals[i] + [offset])*
return average/animals.length;
}
which we could then call with
averageAttribute(animals, &Animal::age);
In summary, pointers to members allow you to abstract a method such as our averageAttribute to all members of a struct without having to copy and paste code. While a delegate can achieve the same functionality, it is a rather inefficient way to get a member of a struct if you know you do not actually need the freedom allotted to you by a function, and there could even be edge use cases in which a delegate does not suffice, but I could not give any examples of such use cases. Does C# have similar functionality?
As other people have commented here, delegates are the way to achieve this in C#.
While a delegate can achieve the same functionality, it is a rather
inefficient way to get a member of a struct if you know you do not
actually need the freedom allotted to you by a function
It depends how the compiler and runtime implement that delegate. They could very well see that this is a trivial function and optimize the call away, like they do for trivial getters and setters. In F# for instance you can achieve this:
type Animal = { Age : int }
let getAge (animal:Animal) =
animal.Age
let inline average (prop:Animal->int) (animals:Animal[]) =
let mutable avg = 0.
for animal in animals do
avg <- avg + float(prop(animal)) // no function call in the assembly here when calling averageAge
avg / (float(animals.Length))
let averageAge = average getAge
You can get the same behaviour using delegates but that's not the same thing as delegates are pointers to functions in C++. What you're trying to achieve is possible in C# but not in the way you're doing in C++.
I think about a solution using Func:
public class Animal
{
public int Age { get; set; }
public int Height { get; set; }
public double Weight { get; set; }
public string Name { get; set; }
public static double AverageAttributeDelegates(List<Animal> animals, Func<Animal, int> getter)
{
double average = 0;
foreach(Animal animal in animals)
{
average += getter(animal);
}
return average/animals.Count;
}
}
List<Animal> animals = new List<Animal> { new Animal { Age = 1, Height = 2, Weight = 2.5, Name = "a" }, new Animal { Age = 3, Height = 1, Weight = 3.5, Name = "b" } };
Animal.AverageAttributeDelegates(animals, x => x.Age); //2
Animal.AverageAttributeDelegates(animals, x => x.Height); //1.5
It's working but you are bound to the int type of the property since the func is declared as Func<Animal, int>. You could set to object and handle the cast:
public static double AverageAttributeDelegates2(List<Animal> animals, Func<Animal, object> getter)
{
double average = 0;
foreach(Animal animal in animals)
{
int value = 0;
object rawValue = getter(animal);
try
{
//Handle the cast of the value
value = Convert.ToInt32(rawValue);
average += value;
}
catch(Exception)
{}
}
return average/animals.Count;
}
Example:
Animal.AverageAttributeDelegates2(animals, x => x.Height).Dump(); //1.5
Animal.AverageAttributeDelegates2(animals, x => x.Weight).Dump(); //3
Animal.AverageAttributeDelegates2(animals, x => x.Name).Dump(); //0
no, c# doesn't have a feature to point into (reference) object's members the way c++ does.
but why?
A pointer is considered unsafe. And even in unsafe area you cannot point to a reference or to a struct that contains references, because an object reference can be garbage collected even if a pointer is pointing to it. The garbage collector does not keep track of whether an object is being pointed to by any pointer types.
you mentioned a lot of duplicate code is used to implement it the non-pointer way, which isn't true.
Speed depends on how well the JIT compiles it, but you didn't test?
if you really run into performance problems, you need to think about your data structures and less about a certain way to access members.
If think the amount of comments under your Q shows, that you did not really hit a commonly accepted drawback of c#
var Animals = new Animal[100];
//fill array
var AvgAnimal = new Animal() {
age = (int)Animals.Average(a => a.age ),
height = (int)Animals.Average(a => a.height),
weight = (int)Animals.Average(a => a.weight)
};
the unsafe area of c# serves some ways access members by pointer, but only to value types like single structs and not for an array of structs.
struct CoOrds
{
public int x;
public int y;
}
class AccessMembers
{
static void Main()
{
CoOrds home;
unsafe
{
CoOrds* p = &home;
p->x = 25;
p->y = 12;
System.Console.WriteLine("The coordinates are: x={0}, y={1}", p->x, p->y );
}
}
}
Related
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 can type
Square[,,,] squares = new Square[3, 2, 5, 5];
squares[0, 0, 0, 1] = new Square();
In fact, I expect I could keep going adding dimensions to Int.MaxValue though I have no idea how much memory that would require.
How could I implement this variable indexing feature in my own class? I want to encapsulate a multi dimensional array of unknown dimensions and make it available as a property thus enabling indexing in this manner. Must I always know the size in which case how does Array work?
EDIT
Thanks for the comments, here is what I ended up with - I did think of params but didn't know where to go after that not knowing about GetValue.
class ArrayExt<T>
{
public Array Array { get; set; }
public T this[params int[] indices]
{
get { return (T)Array.GetValue(indices); }
set { Array.SetValue(value, indices);}
}
}
ArrayExt<Square> ext = new ArrayExt<Square>();
ext.Array = new Square[4, 5, 5, 5];
ext[3, 3, 3, 3] = new Square();
TBH I don't really need this now. I was just looking for a way to extend Array to initialize its elements having resolved to avoid for loop initialization code outside the class whenever I was using a multi array (mainly in unit tests). Then I hit intellisense and saw the Initialize method...though it restricts me to a default constructor and value types. For reference types an extension method would be required. Still I learnt something and yes, there was a runtime error when I tried an array with more than 32 dimensions.
Arrays types are magic – int[] and int[,] are two different types, with separate indexers.
These types are not defined in source code; rather, their existence and behavior are described by the spec.
You would need to create a separate type for each dimensionality – a Matrix1 class with a this[int], a Matrix2 class with a this[int, int], and so on.
You could use varargs:
class Squares {
public Square this[params int[] indices] {
get {
// ...
}
}
}
You'd have to handle the fact indices can have an arbitrary length yourself, in whicheevr way you feel is appropriate. (E.g. check the size of indices against the array rank, type it as Array and use GetValue().)
use the this[] operator:
public int this[int i, int j]
{
get {return 1;}
set { ; }
}
Note that you can't have a variable number of dimensions in one operator - you have to code each method separately:
public int this[int i, int j, int k]
{
get {return 1;}
set { ; }
}
public int this[int i, int j]
{
get {return 1;}
set { ; }
}
public int this[int i]
{
get {return 1;}
set { ; }
}
I expect I could keep going adding dimensions to Int.MaxValue
You'd be wrong:
An array can have a maximum of 32 dimensions.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 9 years ago.
Improve this question
I am using a struct in a project, like so:
struct Position
{
public int X { get; private set; }
public int Y { get; private set; }
// etc
}
I would like to add a method that allows me to create a modified copy of the struct with arbitrarily changed properties. For example, it would be convenient to use this:
var position = new Position(5, 7);
var newPos = position.With(X: position.X + 1);
Is this idiom hacky? Are there better ways to support this?
public Position With(int? X = null, int? Y = null)
{
return new Position(X ?? this.X, Y ?? this.Y);
}
Edit: in case it was unclear, the struct is immutable, I simply want to create a new value with some values modified. Incidentally, this is very similar to Haskell's syntactic sugar for records, where one would write newPos = oldPos { x = x oldPos + 1 }. This is just a bit experimental as to whether such an idiom is helpful in C#.
Personally, I consider the idiom of a plain-old-data-struct to be vastly underrated. Mutable structs which encapsulate state in anything other than public fields are problematic, but sometimes it's useful to bind together a fixed collection of variables stuck together with duct tape so they can be passed around as a unit. A plain-old-data-struct is a perfect fit for that usage; it behaves like a fixed collection of variables stuck together with duct tape, since that's what it is. One can with some work come up with an immutable class which requires slow and hard-to-read code to do anything with, or with some more work come up with something that's still slow but not quite so unaesthetic; one can also code structures in such fashion as to mimic such classes. In many cases, however, the only effect of going through all that effort is that one's code will be slower and less clear than it would have been if one had simply used a PODS.
The key thing that needs to be understood is that a PODS like struct PersonInfo { public string Name, SSN; public Date Birthdate; } does not represent a person. It represents a space that can hold two strings and a date. If one says var fredSmithInfo = myDatabase.GetPersonInfo("Fred Smith");, then FredSmithInfo.BirthDate doesn't represent Fred Smith's birthdate; it represents a variable of type Date which is initially loaded with the value returned by a call to GetPersonInfo--but like any other variable of type Date, could be changed to hold any other date.
That's about as neat a way as you're going to get. Doesn't seem particularly hacky to me.
Although in cases where you're just doing position.X + 1 it'd be neater to have something that was like:
var position = new Position(5,7);
var newPos = position.Add(new Position(1,0));
Which would give you a modified X value but not a modified Y value.
One could consider this approach as a variant of the prototype pattern where the focus is on having a template struct rather than avoiding the cost of new instances. Whether the design is good or bad depends on your context. If you can make the message behind the syntax clear (I think the name With you're using is a bit unspecific; maybe something like CreateVariant or CreateMutant would make the intention clearer), I would consider it an appropriate approach.
I'm adding an expression based form as well. Do note the horrendous boxing/unboxing which needs to be done due to the fact that it is a struct.
But as one can see the format is quite nice:
var p2 = p.With(t => t.X, 4);
var p3 = p.With(t => t.Y, 7).With(t => t.X, 5); // Yeah, replace all the values :)
And the method is really applicable to all kinds of types.
public void Test()
{
var p = new Position(8, 3);
var p2 = p.With(t => t.X, 4);
var p3 = p.With(t => t.Y, 7).With(t => t.X, 5);
Console.WriteLine(p);
Console.WriteLine(p2);
Console.WriteLine(p3);
}
public struct Position
{
public Position(int X, int Y)
{
this._X = X; this._Y = Y;
}
private int _X; private int _Y;
public int X { get { return _X; } private set { _X = value; } }
public int Y { get { return _Y; } private set { _Y = value; } }
public Position With<T, P>(Expression<Func<Position, P>> propertyExpression, T value)
{
// Copy this
var copy = (Position)this.MemberwiseClone();
// Get the expression, might be both MemberExpression and UnaryExpression
var memExpr = propertyExpression.Body as MemberExpression ?? ((UnaryExpression)propertyExpression.Body).Operand as MemberExpression;
if (memExpr == null)
throw new Exception("Empty expression!");
// Get the propertyinfo, we need this one to set the value
var propInfo = memExpr.Member as PropertyInfo;
if (propInfo == null)
throw new Exception("Not a valid expression!");
// Set the value via boxing and unboxing (mutable structs are evil :) )
object copyObj = copy;
propInfo.SetValue(copyObj, value); // Since struct are passed by value we must box it
copy = (Position)copyObj;
// Return the copy
return copy;
}
public override string ToString()
{
return string.Format("X:{0,4} Y:{1,4}", this.X, this.Y);
}
}
using c# i have a list those objects all have a float mass that is randomized when the object is created.
Whats the most efficient way to loop through the list and find the object with the highest mass?
The most efficient way to do this with a simple list will be a simple linear time search, as in
SomeObject winner;
float maxMass = 0.0f; // Assuming all masses are at least zero!
foreach(SomeObject o in objects) {
if(o.mass > maxMass) {
maxMass = o.mass;
winner = o;
}
}
If this is something you intend to do regularly, it may be beneficial to store your objects in an order sorted by mass and/or to use a more appropriate storage container.
Sounds like a perfect candidate for the MaxBy/MinBy operators in morelinq. You could use it as follows:
objects.MaxBy(obj=>obj.Mass)
Implementing IComparable would make things simple and easy to maintain. I have provided an example. Hope this helps.
I am not sure if this is more efficient than looping. I understand that sometimes using linq slightly degrades the performance for the first time when it is invoked.
But definitely many a times maintainable code scores more over slight performance gain. Can someone provide more details on performance of PARALLEL execution vs looping with AsParallel().
class Program
{
delegate int Del();
static void Main(string[] args)
{
List<MyClass> connections = new List<MyClass>();
connections.Add(new MyClass() { name = "a", mass = 5.001f });
connections.Add(new MyClass() { name = "c", mass = 4.999f });
connections.Add(new MyClass() { name = "b", mass = 4.2f });
connections.Add(new MyClass() { name = "a", mass = 4.99f });
MyClass maxConnection = connections.AsParallel().Max();
Console.WriteLine("{0} {1} ", maxConnection.name, maxConnection.mass);
Console.ReadLine();
}
class MyClass : IComparable
{
public string name { get; set; }
public float mass { get; set; }
public int CompareTo(object obj)
{
return (int)(mass - ((MyClass)obj).mass);
}
}
}
The simplest and most efficient solution (assuming repeated queries) is to sort the list by size.
i.e.
private int SortByMass(ObjectWithMass left,ObjectWithMass right)
{
return left.Mass.CompareTo(right.Mass);
}
List<ObjectWithMass> myList = MyFunctionToPopulateTheList();
myList.sort(SortByMass);
Once the list is sorted, the first element will be the smallest, and the last will be the largest.
You can use myList.Reverse() if you want it by largest to smallest.
This runs in o(nlog(n)) to sort, and then finding the largest object is myList[myList.Count -1]. which is o(1) for .net lists (they are actually arrays underneath)
If you're willing to trade a little space for time then, in one of the instance constructors, have something like the following
public Foo(Foo min, Foo max)
{
min = min ?? new Foo();
max = max ?? new Foo();
if(max.mass < this.mass)
max = this;
if(min > this.mass)
min = this;
}
And upon object creation have the calling method pass those paramters.
Foo min, max = null;
//Create a bunch of Foo objects
var Foos = from n in Enumerable.Range(0, 10000) select new Foo(min, max);
I wonder if there's any way something like this would be possible for value types...
public static class ExtensionMethods {
public static void SetTo(this Boolean source, params Boolean[] bools) {
for (int i = 0; i < bools.Length; i++) {
bools[i] = source;
}
}
}
then this would be possible:
Boolean a = true, b, c = true, d = true, e;
b.SetTo(a, c, d, e);
Of course, this does not work because the bools are a value type so they are passed into the function as a value, not as a reference.
Other than wrapping the value types into reference types (by creating another class), is there any way to pass a variable into function by the reference (ref) while using params modifier?
This is not possible. To explain why, first read my essay on why it is that we optimize deallocation of local variables of value type by putting them on the stack:
https://web.archive.org/web/20100224071314/http://blogs.msdn.com/ericlippert/archive/2009/05/04/the-stack-is-an-implementation-detail-part-two.aspx
Now that you understand that, it should be clear why you cannot store a "ref bool" in an array. If you could, then you could have an array which survives longer than the stack variable being referenced. We have two choices: either allow this, and produce programs which crash and die horribly if you get it wrong -- this is the choice made by the designers of C. Or, disallow it, and have a system which is less flexible but more safe. We chose the latter.
But let's think about this a little deeper. If what you want is to pass around "thing which allows me to set a variable", we have that. That's just a delegate:
static void DoStuff<T>(this T thing, params Action<T>[] actions)
{
foreach(var action in actions) action(thing);
}
...
bool b = whatever;
b.DoStuff(x=>{q = x;}, x=>{r = x;} );
Make sense?
There isn't really a way. You could do something like this:
public static void Main(string[] args)
{
BooleanWrapper a = true, b = true, c = true, d = true, e = new BooleanWrapper();
b.SetTo(a, c, d, e);
}
public static void SetTo(this BooleanWrapper sourceWrapper, params BooleanWrapper[] wrappers)
{
foreach (var w in wrappers)
w.Value = sourceWrapper.Value;
}
public class BooleanWrapper
{
public BooleanWrapper() { }
public BooleanWrapper(Boolean value)
{
Value = value;
}
public Boolean Value { get; set; }
public static implicit operator BooleanWrapper(Boolean value)
{
return new BooleanWrapper(value);
}
}
But then again how is that any better than just doing this:
public static void Main(string[] args)
{
Boolean[] bools = new Boolean[5];
bools.SetTo(bools[1]); // Note I changed the order of arguments. I think this makes more sense.
}
public static void SetTo(this Boolean[] bools, Boolean value)
{
for(int i = 0; i < bools.Length; i++)
bools[i] = value;
}
After all, an array is a sequence of variables. If you need something that behaves like a sequence of variables, use an array.
Unfortunately the community of Java, and now .NET, developers decided that less flexibility in the name of "safety" is the preferred solution, and to achieve the same result with less lines of code you have to opt for extraordinary complexity (all those class structures, delegates, etc.).
In Delphi I could simply do something like this:
var
a: integer; f: double; n: integer;
sscanf(fmtstr, valuestr, [#a, #f, #n]);
//<-- "sscanf" is a function I wrote myself that takes an open array of pointers.
In C# You would have to do:
int a; double f; int n;
object [] o = new object[];
sscanf(fmtstr, valuestr, ref o);
a = o[0];
f = o[1];
n = o[2];
That's 5 lines of code to do what I could do in 1 line of Delphi code. I think there is a formula somewhere that the likelihood of bugs in code increases geometrically with the number of lines of code; so if you have 20 lines of code you're code is 4 times more likely to have bugs than if you have 10.
Of course, you can decrease your # lines of code by using the delegate with all those weird angle brackets and strange syntax, but I would think that's also a haven for bugs.
Here is some interesting solution:
public delegate RecursionRefFunc<T> RecursionRefFunc<T>(ref T arg);
public static RecursionRefFunc<T> Boo<T>(ref T input)
{
Console.WriteLine(input); // Work in here
return Boo;
}
public static void Main(string[] args)
{
int x1 = 1, x2 = 2, x3 = 3, x4 = 4, x5 = 5;
Boo(ref x1)(ref x2)(ref x3)(ref x4)(ref x5);
}
// Output: //
// 1
// 2
// 3
// 4
// 5
Delegate can declare in recursion.
Return a function outside and call again.
And you will be killed by the code reviewer.
Advertisement OW<: CWKSC/MyLib_Csharp
This would not be possible even if bools were reference types. While a class is a reference type, the variable in the Boolean[] is still a value, it's just that the value is a reference. Assigning the value of the reference just changes the value of that particular variable. The concept of an array of ref variables doesn't make sense (as arrays are, by their nature, a series of values).