0

I have the following public struct in C#:

public struct Route
{
    public float Start; 
    public float End; 
    public float Range; 
    public bool InConstruction; 
};

I want to replace every property Range of Route used as an array of struct in an other class (Route[]). I did the following which works fine:

//dest.Route = new Route[]; 
for (var i = 0; i < dest.Route.Count; i++)
{
    dest.Route[i].Range = dest.Route[i].End - dest.Route[i].Start; 
}

Is there a way to optimize this loop or just other ways to implement this solution?

Maybe with desc.Route.Select(i => i.Range = i.End - i.Start); ?

4
  • 3
    Why not define Range as a computed property, like public float Range => End - Start;? That way you don't have to recompute it again. Commented Jul 18, 2022 at 3:27
  • That's just an example here. This struct is used multiple time in the project and it can't be change. And the solution I have works fine. It simply curiosity on how to implement this solution other ways. Commented Jul 18, 2022 at 3:30
  • 2
    @user14645785 Sounds like an XY problem. Can you tell us why it cannot be changed? If you need the computation to be on-demand, you can add a method to the struct named something like CalculateRange. Then, you can do foreach (var route in desc.Route) route.CalculateRange();. Or if desc.Route is a list: desc.Route.ForEach(r => r.CalculateRange());. Commented Jul 18, 2022 at 3:33
  • Oh ok thanks, I thought their might be a way to implement this solution with var temp = desc.Route.Select(i => i.Range = i.End - i.Start); Commented Jul 18, 2022 at 3:37

1 Answer 1

1

If you can't change the struct, then no, you've done the most optimal thing. Even if you do find some solution with Linq, it's eventually just going to boil down to a loop like you have.

If you're dead set on using Linq, you'd need to do something like this:

desc.Route = desc.Route.Select(d => {
    d.Range = d.End - d.Start;
    return d;
})
.ToArray();

I'll let you be the judge if that's "better" for your project or not. This does go against some of the principles of Linq, mostly the "don't cause side effects".

This:

.Select(i => i.Range = i.End - i.Start)

Doesn't work (though it is legal syntax) because the assignment operator returns the value that was assigned, so you'd be selecting just the float assigned to the Range property, not the full Route object. https://dotnetfiddle.net/jSKZlj


If you can change the struct:

If Range is always the End field minus the Start field, then you could just compute it when you need to read the value, rather than preemptively. Shamelessly taking Etienne de Martel's idea:

public struct Route
{
    public float Start; 
    public float End; 
    public float Range => End - Start;
    public bool InConstruction; 
};

Now there's no need to do the loop calculation at all. The value for each object will be calculated as soon as you read the Range property.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.