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);
}
}
Related
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 );
}
}
}
Been bouncing back and forth between Swift and C# and I'm not sure if I'm forgetting certain things, or if C# just doesn't easily support what I'm after.
Consider this code which calculates the initial value for Foo:
// Note: This is a field on an object, not a local variable.
int Foo = CalculateInitialFoo();
static int CalculateInitialFoo() {
int x = 0;
// Perform calculations to get x
return x;
}
Is there any way to do something like this without the need to create the separate one-time-use function and instead use an instantly-executing lambda/block/whatever?
In Swift, it's simple. You use a closure (the curly-braces) that you instantly execute (open and closed parentheses), like this:
int Foo = {
int x = 0
// Perform calculations to get x
return x
}()
It's clear, concise and doesn't clutter up the object's interface with functions just to initialize fields.
Note: To be clear, I do NOT want a calculated property. I am trying to initialize a member field which requires multiple statements to do completely.
I wouldn't suggest doing this, but you could use an anonymous function to initialize
int _foo = new Func<int>(() =>
{
return 5;
})();
Is there a reason you would like to do it using lambdas rather than named functions, or as a calculated property?
I assume you want to avoid calculated properties because you want to either modify the value later, or the computation is expensive and you want to cache the value.
int? _fooBacking = null;
int Foo
{
get
{
if (!_fooBacking.HasValue)
{
_fooBacking = 5;
}
return _fooBacking.Value;
}
set
{
_fooBacking = value;
}
}
This will use what you evaluate in the conditional the first time it is gotten, while still allowing the value to be assigned.
If you remove the setter it will turn it into a cached calculation. Be careful when using this pattern, though. Side-effects in property getters will be frowned upon because they make the code difficult to follow.
To solve the problem in the general case you'd need to create and then execute an anonymous function, which you can technically do as an expression:
int Foo = new Func<int>(() =>
{
int x = 0;
// Perform calculations to get x
return x;
})();
You can clean this up a bit by writing a helper function:
public static T Perform<T>(Func<T> function)
{
return function();
}
Which lets you write:
int Foo = Perform(() =>
{
int x = 0;
// Perform calculations to get x
return x;
});
While this is better than the first, I think it's pretty hard to argue that either is better than just writing a function.
In the non-general case, many specific implementations can be altered to run on a single line rather than multiple lines. Such a solution may be possible in your case, but we couldn't possibly say without knowing what it is. There will be cases where this is possible but undesirable, and cases where this may actually be preferable. Which are which is of course subjective.
You could initialize your field in the constructor and declare CalculateInitialFoo as local function.
private int _foo;
public MyType()
{
_foo = CalculateInitialFoo();
int CalculateInitialFoo()
{
int x = 0;
// Perform calculations to get x
return x;
}
}
This won't change your code too much but you can at least limit the scope of the method to where it's only used.
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 7 years ago.
Improve this question
I never liked out and ref parameters.When I see them in action they give me a feeling that something is messy about the design.
I thought that the only exception was the so called TryXXX pattern that returns a boolean as the function result (whether everything was fine or something went wrong) and an out parameter for the real result, until I read this article today and It made me think if there's a better pattern to implement this kind of methods.
I thought that we could either have a function that returns more than one result(or as the article says a tuple)
Tuple<Exception,T> TryParseT(object obj)
or a function that accepts a callback function for success :
void TryParseT(object obj,Action<T> success)
The question is , which one is better from a functional design point of view ?
UPDATE :
To rephrase my question , I want to know which of these two functions more complies with Functional Programming principles and why ?
Essentially the problem is that to follow the functional programming approach you should always provide a return value for an input value. So the returning void route isn't the way to go. You need to return a value that can represent success (and hold the successful result) and failure (and hold no result).
The closest to that is where you have returned a Tuple which includes the exception. However you then don't have the 'infrastructure' to deal with the Tuple reliably once you've got it. So the code scaffolding around it will be repeated.
Take a look at this library language-ext. It deals with improving the out problem for TryParse using its implementation of Option<T>.
string inp = "123";
// Attempts to parse the value, uses 0 if it can't
int value1 = parseInt(inp).IfNone(0);
// Functional alternative to above
// Attempts to parse the value, uses 0 if it can't
int value2 = ifNone(parseInt(inp), 0);
// Attempts to parse the value and then pattern matches the result
int value3 = parseInt(inp).Match(
Some: x => x * 2,
None: () => 0
);
// Functional alternative to above
// Attempts to parse the value and then pattern matches the result
int value4 = match( parseInt(inp),
Some: x => x * 2,
None: () => 0
);
The library also allows you to just check that something is valid:
if( parseInt(inp) )
return 1;
else
return 0;
And allows for comparisons without actually extracting the value:
if( parseInt(inp) == 123 )
return 123;
else
return 0;
As well as logical operations:
var allValid = parseInt(x) && parseInt(y) && parseInt(z);
var someValid = parseInt(x) || parseInt(y) || parseInt(z);
And finally LINQ expressions which can often remove the need for if-then-else or matching:
var res = from x in parseInt(inp1)
from y in parseInt(inp2)
from z in parseInt(inp3)
select x + y + z;
It also has TryGetValue extensions for IDictionary, IReadOnlyDictionary, IImmutableDictionary and IImmutableSet that instead return Option<T> and can be used as above.
The most elegant method is
int Parse(string value)
The Tryxxxx methods only exist for an implementation detail named performance. If you are seeking elegance you can use the Parse method and handle any errors by failing fast.
You can instead return a tuple but this will cost an additional allocation on the heap since Tuple is a reference type.
A better solution in terms of performance (if you care) would be aKeyValuePair. But it hides (like tuple) the semantics behind generic data types which is not optimal for code clarity. A better way to signal failure than by defining some convention that the first bool of the tuple contains the failure state is by defining your own data type.
struct ParseResult<T>
{
public bool Success { get; private set; }
public T Value { get; private set; }
public ParseResult(T value, bool success):this()
{
Value = value;
Success = success;
}
}
class Program
{
static ParseResult<int> TryParse(string s)
{
int lret = 0;
if (int.TryParse(s, out lret))
{
return new ParseResult<int>(lret, true);
}
else
{
return new ParseResult<int>(lret, false);
}
}
static void Main(string[] args)
{
string test = "1";
var lret = TryParse(test);
if( lret.Success )
{
Console.WriteLine("{0}", lret.Value);
}
}
}
That approach is still quite efficient and spares you the out parameters at the cost of the allocation of a cheap container object.
I've been trying to write a program which can scan a raw data file and normalize it for data mining processes, I've trying to read the data from the file and store it in a list this way:
public static List<Normalize> NF()
{
//Regex r = new Regex(#"^\d+$");
List<Normalize> N = new List<Normalize>();
StreamReader ss = new StreamReader(#"C:\Users\User\Desktop\NN.txt");
String Line = null;
while (!ss.EndOfStream) {
Line = ss.ReadLine();
var L = Line.Split(',').ToList();
N.Add(new Normalize { age = Convert.ToInt16(L[0]),
Sex = L[1],
T3 = Convert.ToDouble(L[2]),
TT4 = Convert.ToDouble(L[3]),
TFU = Convert.ToDouble(L[4]),
FTI = Convert.ToDouble(L[5]),
RC = L[6],
R = L[7]
});
}
return N;
}
}
struct Normalize {
public int age;
public String Sex;
public double T3;
public double TT4;
public double TFU;
public double FTI;
public String RC;
public String R;
}
At this moment I want to go through the list that I've made and categorize the data , similar to this :
var X= NF();
for (int i = 0; i < X.Count; i++) {
if (X[i].age > 0 && X[i].age <= 5) { // Change the X[i].age value to 1 }
else if (X[i].age > 5 && X[i].age <= 10) { // Change the X[i].age value to 2 }
...
}
But the compiler says X[i].[variable name] is not a variable and cannot be modified in this way. My question is, what would be an efficient way to perform this operation.
struct Normalize is a value type, not a reference type, therefore you cannot change its fields like that. Change it to class Normalize
Change struct Normalize to class Normalize and iterate with foreach loop. It's way cleaner.
You could also set variables to private and use getters/setters to check/set variable.
foreach (Normalize x in X)
{
if (x.getAge() > 0 && x.getAge() <= 5)
x.setAge(1)
...
}
Edit:
just saw you already got your answer
Modifying struct field is fine as long as it's a single entity (Given its a mutable struct). This is possible -
var obj = new Normalize();
obh.Age = 10;
But in your case you are accessing the struct using indexer from the list.
Indexer will return copy of your struct and modifying the value won't reflect it back to the list which ain't you want.
Hence compiler is throwing error to stop you from writing this out.
As Alex mentioned, you should go for creating class instead of struct if you want to modify it.
On a side note, its always advisable to have immutable structs instead of mutable structs.
I'm not quite sure how to ask my question in C# terms, so please bear with the long-winded explanation.
I'm writing a stock trading algorithm. When the algo starts, it checks to see what kind of instrument it is applied to (in this case, either stock or futures), and then depending on the instrument, assigns a value to "double x".
If its a future instrument, then the assignment is a simple, flat value (in this case, "double x = 5;). However, if its a stock, I'd like "x" to be assigned to a value from another object - lets call the object "Algo2" and the value "y". So, in my script the assignment is as follows: "double x = Algo2.y" (note: that's the convention in the editor I'm using). This block of code is run only once when the algorithm begins.
What I'm trying to achieve here is to tell my algorithm to get the latest value of "Algo2.y" whenever "x" is used in a formula such as "EntryValue = Price + x". However, whats happening is that "x" is permanently assigned the value of "Algo2.y" at the start of the program, and since that block is never run again, remains that constant value throughout.
Can anyone help with the syntax so that instead of assigning a value to "x", it simply points to get the latest value of "Algo2.y" whevever it's called?
Thanks!
Make 'x' a property, so that it fetches the value each time you ask for x.
class StockInstrument
{
public double Value //x isn't a good name, I'll use "Value"
{
get
{
if(...) return 5.0;
else return Algo2.y;
}
}
}
Write a function for it:
double getAlgo2YValue()
{
return Algo2.y; // or Algo2.getY(), another function if you can't access it
}
In your main algorithm, now call:
x = getAlgo2YValue();
To update X.
I would use a method to return your latest value
public double GetXValue()
{
if (AlgoType == Algos.Futures)
{
return 5.0;
}
else if (AlgoType == Algos.Stock)
{
return Algo2.y;
}
//else
throw new Exception("unknown algo type");
}
This is quite hard coded, but it could be cleaned up using delegates and encapsulation of the algorithms, but at a low level - this is the idea. Also, some people prefer to use properties for this - Just don't use properties when the get has modifying affects
public double X
{
get
{
if (AlgoType == Algos.Futures)
{
return 5.0;
}
else if (AlgoType == Algos.Stock)
{
return Algo2.y;
}
//else
throw new Exception("unknown algo type");
}
}
May use something like:
double X {
get {
if(isStock())
return Algo2.y;
else
return 5;
}
}
Func<int> getX;
if(isFuture)
getX = () => 5;
else
getX = () => Algo.y;
// using getX() will always return the current value of Algo.y,
// in case it's a stock.
int xval = getX();
Give Algo2 a reference to Algo so that no 'double X' copy is needed. Algo can then dereference the actual value in Algo2 at any time, (thread-safety an issue?).
Value data types, such as int are always going to be copied by value, not as a reference. However, what you can do is architect your solution a little differently, and then it will provide the right value. For example:
public class ValueContainer
{
protected Algo2 _reference = null;
protected double _staticValue = 0;
public double CurrentValue
{
get
{
if(_reference == null)
return _staticValue;
return _reference.y;
}
}
public ValueContainer(Algo2 reference)
{
_reference = reference;
}
public ValueContainer(double value)
{
_staticValue = value;
}
}
Then, you replace your x with the ValueContainer instance wherever needed and use the CurrentValue property to get the value. You create each version with a different constructor then:
ValueContainer container = null;
if(stock)
container = new ValueContainer(5);
else
container = new ValueContainer(Algo2);
What you need is a property wrapper for x to control the value that's returned, based on the instrument type. Here's an example, which will require some significant adaptation for your app.
public class Instrument
{
// an example enum holding types
public InstrumentType Type {get; set;}
// x is not a great name, but following your question's convention...
public double X
{
get
{
if(type == InstrumentType.Stock)
return Algo2.y();
// note that I changed this to be a method rather than a property
// Algo2.y() should be static so it can be called without an instance
else if(type == InstrumentType.Future)
return 5.0;
else
// return some default value here
}
}
}