Avinash Reddy
Avinash Reddy

Reputation: 937

How to swap a long variable present in list of a class with swap method

I have a list public List<ArticleWarehouseLocations> ArticleWarehouseLocationsList. In this list I have a property called Position.

`Swap<long>(ref ArticleWarehouseLocationsList[currentIndex].Position, ref ArticleWarehouseLocationsList[currentIndex - 1].Position);`
    public void Swap<T>(ref T lhs, ref T rhs)
     {
       T temp = lhs;
       lhs = rhs;
       rhs = temp;
      }

I'm trying to do something like this. It's giving me an error property or index may not be passed as ref or out.

I can use a local variable and assign it the value and use it but I'm looking for a global solution.

Upvotes: 1

Views: 78

Answers (2)

Lesiak
Lesiak

Reputation: 25976

I believe the tuple swap (x, y) = (y, x) proposed in comments is the way to go, but wanted to share yet another aproach with LINQ Expressions (a bit too long for a comment, so posting as an answer)

public static void SwapProperties<T>(T lhs, T rhs, Expression<Func<T, object>> propExpression)
{
    var prop = GetPropertyInfo(propExpression);
    var lhsValue = prop.GetValue(lhs);
    var rhsValue = prop.GetValue(rhs);
    prop.SetValue(lhs, rhsValue);
    prop.SetValue(rhs, lhsValue);
}

private static PropertyInfo GetPropertyInfo<T>(Expression<Func<T, object>> propExpression)
{
    PropertyInfo prop;
    if (propExpression.Body is MemberExpression memberExpression)
    {
        prop = (PropertyInfo) memberExpression.Member;
    }
    else
    {
        var op = ((UnaryExpression) propExpression.Body).Operand;
        prop = (PropertyInfo) ((MemberExpression) op).Member;
    }
    return prop;
}

class Obj
{
    public long Position { get; set; }
    public string Name { get; set; }
}

public static void Main(string[] args)
{
    var a1 = new Obj()
    {
        Position = 10,
        Name = "a1"
    };
    var a2 = new Obj()
    {
        Position = 20,
        Name = "a2"
    };
    SwapProperties(a1, a2, obj => obj.Position);
    SwapProperties(a1, a2, obj => obj.Name);

    Console.WriteLine(a1.Position);
    Console.WriteLine(a2.Position);

    Console.WriteLine(a1.Name);
    Console.WriteLine(a2.Name);
}

Upvotes: 1

Serve Laurijssen
Serve Laurijssen

Reputation: 9733

What you can do is make the property return by reference:

class Obj {
    private long pos;
    public ref long Position { get { return ref pos; } }
}

static void Main(string[] args)
{
        Obj[] arr = new Obj[2] { new Obj(), new Obj() };

        arr[0].Position = 10;
        arr[1].Position = 20;

        int index = 0;

        WriteLine($"{arr[index].Position}, {arr[index+1].Position}");
        Swap<long>(ref arr[index].Position, ref arr[index+1].Position);
        WriteLine($"{arr[index].Position}, {arr[index+1].Position}");
}

https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/ref-returns

Upvotes: 2

Related Questions