Linq: How to assign local variables within linq from array - c#

I have a method that returns a simple int[2]. Both elements of the array need to each be assigned to an int r and int c local variables. I want to achieve this all within a single Linq query. Any way to do this?
This is pseudo code of what I want to achieve, but obviously it doesn't work. I don't know Linq very well and I'm trying to get better at it. Method(r,c) is the method that returns an int[2]. I want to pull each element out and assign int[0] = r and int[1] = c.
void Foo(int r, int c)
{
Method(r,c).Select(([0],[1]) => { r = [0]; c = [1]; });
}
int[] Method(int r, int c)
{
///stuff///
}

logic:
Method return int array with r and c
create static class to make a Select method
Select method input the int array and call Func<int[],T> and retrun T (T is Generic)
Online Test Demo Link
public class Program
{
public static void Main()
{
var result = Method(1, 2).Select( (r,c) => new { r,c });
Console.WriteLine(result);
}
static int[] Method(int r,int c) => new[] {r,c};
}
public static class LinqExtension
{
public static T Select<T>(this int[] ints, Func<int,int, T> func) => func(ints[0],ints[1]);
}
or you can use Method with params int[]
public class Program
{
public static void Main()
{
var value = Method(1, 2).Select((int[] arr) => new{r = arr[0],c = arr[1]});
Console.WriteLine(value); //result : { r = 1, c = 2 }
}
public static int[] Method(params int[] ints)
{
return ints;
}
}
public static class LinqExtension
{
public static T Select<T>(this int[] ints,Func<int[],T> func){
return func(ints);
}
}
new question :
How would I use in out keywords in this context? Assuming I'm using parameters passed by value from Foo().
you can use out keyword :
public class Program
{
public static void Main()
{
Method(1, 2).Select( out int r ,out int c);
Console.WriteLine(r);
Console.WriteLine(c);
}
static int[] Method(int r,int c) => new[] {r,c};
}
public static class LinqExtension
{
public static void Select(this int[] ints, out int r, out int c)
{
r = ints[0];
c = ints[1];
}
}

Related

Given these three similar methods, how we can condense them into a single method?

public int Add2(int a, int b) => a + b;
public int Add3(int a, int b, int c) => a + b + c;
public int Add4 (int a,int b,int c,int d) => a + b + c + d;
How can we write these methods under a single method?
Use params int[] in your Add method and you can add as many numbers as you'd like.
Something like:
using System;
public class Program
{
public static void Main()
{
Console.WriteLine(Add(1, 2, 3, 4, 5));
}
public static int Add(params int[] numbers)
{
int sum = 0;
foreach (int n in numbers)
{
sum += n;
}
return sum;
}
}
Result:
15
Fiddle Demo
Enhancement
With Linq, the code get's shorter
using System;
using System.Linq;
public class Program
{
public static void Main()
{
Console.WriteLine(Add(1, 2, 3, 4, 5));
}
public static int Add(params int[] numbers)
{
return numbers.Sum();
}
}
Result:
15
Fiddle Demo
Try optional arguments.
https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/named-and-optional-arguments#optional-arguments
Write a method A with
Add (int a, int b, int c = 0, int d = 0) { }
Then based on value passed in c and d param do calculation.
The value a and b are always used in three functions. These values are mandatory in your function. The value c and d aren't always used. If you want to combine all of the functions, just make these values optional by giving them default value.
public int Add(int a, int b, int c = 0, int d = 0){
return a + b + c + d;
}
Yet-another-way..fun with Func and (also) Linq :)
static Func<int[], int> Add = ((i) => i.Sum());
public static void Main()
{
Console.WriteLine(Add.Invoke(new[] {1,2,3,4,5}));
Console.WriteLine(Add.Invoke(new[] {8}));
Console.WriteLine(Add.Invoke(new[] {-2, -4, 6}));
}
//15
//8
//0

c# - Call the good overloaded method from a function with an unkown parameter type

I am trying to call the good overloaded method from a function with an unkown parameter type. But I always got a conversion error.
How Could I do this ?
Ps I am Trying to not use a if to check the Type.
I Have Try To Change my function to be generic but I got a conversion error.
"Impossible to convert ref T in ref MYPROGRAM.MYCLASS.Struct1"
My Program:
public struct Struct1
{...}
public struct Struct2
{...}
public void EditStruct(ref Struct1 StrucToEdit)
{...}
public void EditStruct(ref Struct2 StrucToEdit)
{...}
public void MyFunction<T>(ref T UnknownStruct)
{
EditStruct(ref UnknownStruct)
}
Thx a lot.
Here is a simple solution using reflection. In this case the reflection results can be very good cached, the performance hit should not be that bad.
class Program
{
static void Main(string[] args)
{
var x = new Struct1() { A = 0, B = -10 };
var y = new Struct2() { C = 0, D = -10 };
MyFunction(ref x);
MyFunction(ref y);
}
public static void EditStruct(ref Struct1 structToEdit)
{
structToEdit = new Struct1() { A = 10, B = 20 };
}
public static void EditStruct(ref Struct2 structToEdit)
{
structToEdit = new Struct2() { C = 30, D = 40 };
}
private delegate void EditDelegate<T>(ref T obj);
public static void MyFunction<T>(ref T unknownStruct)
{
Delegate d;
if (!_dict.TryGetValue(typeof(T), out d))
{
d = typeof(Program).Assembly.GetTypes()
.SelectMany(x => x.GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance | BindingFlags.DeclaredOnly))
.Single(x => x.Name == "EditStruct" && x.GetParameters().SingleOrDefault(y => y.ParameterType.Equals(typeof(T).MakeByRefType())) != null)
.CreateDelegate(typeof(EditDelegate<T>));
_dict.Add(typeof(T), d);
}
(d as EditDelegate<T>)(ref unknownStruct);
}
private static readonly Dictionary<Type, Delegate> _dict = new Dictionary<Type, Delegate>(new TypeComparer());
class TypeComparer : IEqualityComparer<Type>
{
public bool Equals(Type x, Type y) => x.Equals(y);
public int GetHashCode(Type obj) => obj.GetHashCode();
}
}
public struct Struct1
{
public int A;
public int B;
}
public struct Struct2
{
public int C;
public int D;
}
Very small OO example that might help - in this example the code to perform the editing is encapsulated away using the IStructEditor interface:
public static class StructEditor
{
public static void Edit<TStruct, TEditor>(ref TStruct s)
where TEditor : IStructEditor<TStruct>, new()
{
new TEditor()
.EditStuct(ref s);
}
}
public interface IStructEditor<T>
{
void EditStuct(ref T s);
}
struct CostStruct
{
public int Cost;
}
class SetCost
: IStructEditor<CostStruct>
{
public void EditStuct(ref CostStruct s)
{
s.Cost = 123;
}
}
So you can use this as follows:
CostStruct s = new CostStruct();
StructEditor.Edit<CostStruct, SetCost>(ref s);
Meaning you can quickly define new behaviors by implementing IStructEditor!
I dont' even understand what are you doing, but it seams unnecessary to do any casting on a generic method, the type is already known!
Just call EditStruct(ref UnknownStructCasted), deleting first line.
Parameter is of type T, not dynamic. It will be only if you call your method
EditStruct(new dynamic{
//some data
});
Aren't you?
Working sample:
internal class Program
{
public enum WhatToDo
{
Something,
SomethingElse
}
public static void MyMethod(WhatToDo what)
{
switch (what)
{
case WhatToDo.Something:
Struct1 param1 = new Struct1();
MygenericMethod(param1);
break;
case WhatToDo.SomethingElse:
Struct2 param2 = new Struct2();
MygenericMethod(param2);
break;
}
}
public static void MygenericMethod<T>(T someParam) where T : struct
{
}
public struct Struct1
{
}
public struct Struct2
{
}
}
If you can find a common interface for your structs, consider something like:
class Program
{
static void Main(string[] args)
{
IStruct s1 = new Struct1();
IStruct s2 = new Struct2();
EditStruct(ref s1);
EditStruct(ref s2);
}
static void EditStruct(ref IStruct target)
{
target.Name = Guid.NewGuid().ToString();
}
}
public interface IStruct
{
string Name { get; set; }
}
public struct Struct1 : IStruct
{
public string Name { get; set; }
}
public struct Struct2: IStruct
{
public string Name { get; set; }
}

Filtering unique data with Column combinations in C#

I have a list as following:
public class MyClass
{
public int val1;
public long val2;
public string val3;
}
class Program
{
static void Main(string[] args)
{
List<MyClass> lstData=new List<MyClass>
{
new MyClass{val1=1,val2=2,val3="AA"},
new MyClass{val1=1,val2=2,val3="BB"},
new MyClass{val1=3,val2=4,val3="AA"},
new MyClass{val1=3,val2=4,val3="BB"},
new MyClass{val1=1,val2=2,val3="BB"},
new MyClass{val1=3,val2=4,val3="AA"},
};
}
}
I want to get unique rows out of the list.In the above example following lists are duplicate
{val1=1,val2=2,val3="BB"}
{val1=3,val2=4,val3="AA"}
I want to eliminate the duplicate rows and get the distinct rows out of the list.
How I can do that?
var result = lstData.GroupBy(x=>new {x.val1, x.val2, x.val3}, (x,y)=>y.First())
.ToList();
Assuming that your real class MyClass overrides Equals and GetHashCode, all you need is to add Distinct:
lstData = lstData.Distinct().ToList();
You have to either implement GetHashCode and Equals methods on your MyClass class, or define custom class which implements IEqualityComparer<MyClass>.
public class MyClassEqualityComparer : IEqualityComparer<MyClass>
{
private static Lazy<MyClassEqualityComparer> _instance = new Lazy<MyClassEqualityComparer>(() => new MyClassEqualityComparer());
public static MyClassEqualityComparer Instance
{
get { return _instance.Value; }
}
private MyClassEqualityComparer() { }
public bool Equals(MyClass x, MyClass y)
{
return x.val1 == y.val1 && x.val2 == y.val2 && x.val3 == y.val3;
}
public int GetHashCode(MyClass obj)
{
return obj.val1.GetHashCode() ^ obj.val2.GetHashCode() ^ obj.val3.GetHashCode();
}
}
With that you'll be able to use LINQ Distinct() method:
var distinct = lstData.Distinct(MyClassEqualityComparer.Instance).ToList();

C#, Updating a List using a delegate function as a filter

I want to update a list of objects(mycapsule, has many other members) when a condition (pred) holds for one of its class members(value). Whenever I change something another thing fails, I'm newbie in C# and really confused.
Can somebody fix my code:
In the best condition I only get get this error but I think many things are missing in my code
The type or namespace name `T' could not be found. Are you missing a using directive or an assembly reference?
here is my code
using System;
using System.Collections.Generic ;
namespace test
{
class MainClass
{
public static List< mycapsule<int,double> > sample= new List< mycapsule<int,double>>();
public static void Main (string[] args)
{
sample.Add(new mycapsule<int,double> {id=1 , value= 1.2});
update(pred, 12.3);
}
public static bool pred(double x)
{
if (x==2.5) return true;
return false;
}
public class mycapsule<KT, T>
{
public KT id {get ; set; }
public T value { get ; set; }
public int p; // and more
}
public bool update(Func<T, bool> predicate, T i)
{
foreach (var x in sample.FindAll(item => predicate(JustValue(item))) )
{
x.value = i ;
}
return true ;
}
public T JustValue(mycapsule<int,T> i)
{
return i.value;
}
}
}
Look at your update method:
public bool update(Func<T, bool> predicate, T i)
{
foreach (var x in KeyRecord.FindAll(item => predicate(JustValue(item))) )
{
x.value = i ;
}
return true ;
}
What do you expect T to be here? The method is not generic (it's not written as update<T>) and it's not declared in a generic class.
It's possible that you just want:
public bool update<T>(Func<T, bool> predicate, T i)
... but it's hard to say without knowing what KeyRecord.FindAll looks like. Oh, and you've got the same problem with JustValue.
As a side issue, the method names update and pred don't follow .NET naming conventions, and JustValue is a poor method name in terms of descriptiveness. mycapsule also doesn't follow .NET naming conventions. These things really matter in terms of readability.
I'm afraid this won't work due to type safety reasons. I corrected the code as much as possible and got this:
public static List<mycapsule<int, double>> sample = new List<mycapsule<int, double>>();
public static void Main(string[] args)
{
sample.Add(new mycapsule<int, double> { id = 1, value = 1.2 });
update(pred, 12.3);
}
public static bool pred(double x)
{
if (x == 2.5) return true;
return false;
}
public class mycapsule<KT, T>
{
public KT id { get; set; }
public T value { get; set; }
public int p; // and more
}
public static bool update<T>(Func<T, bool> predicate, T i)
{
List<mycapsule<int, double>> list = sample.FindAll(item => predicate(JustValue(item)));
foreach (var x in list)
{
x.value = i;
}
return true;
}
public static T JustValue<T>(mycapsule<int, T> i)
{
return i.value;
}
The error is:
predicate(JustValue(item)) => Argument 1: cannot implicitly convert from double to T
This comes from the fact that you are trying to forcefully call a method that you've specified as taking a generic type T (Func<T, bool>) with a value that is known to be double. Although we know that T will be double from the call to update(pred, 12.3);, nothing prevents me from passing in a predicate that takes an incompatible type e.g.:
public static bool pred(string x)
{
return false;
}
and
update(pred, "asdf");
Which is clearly inconsistent. The compiler is simply trying to prevent you from shooting yourself in the foot accidentally.
To solve this, you could explicitly pass the collection to the update method, thus ensuring that the types are consistent:
public static List<mycapsule<int, double>> sample = new List<mycapsule<int, double>>();
public static void Main(string[] args)
{
sample.Add(new mycapsule<int, double> { id = 1, value = 1.2 });
update(pred, 12.5, sample);
}
public static bool pred(double x)
{
if (x == 2.5) return true;
return false;
}
public class mycapsule<KT, T>
{
public KT id { get; set; }
public T value { get; set; }
public int p; // and more
}
public static bool update<T>(Func<T, bool> predicate, T i, List<mycapsule<int, T>> list)
{
foreach (var x in list.FindAll(item => predicate(JustValue(item))))
{
x.value = i;
}
return true;
}
public static T JustValue<T>(mycapsule<int, T> i)
{
return i.value;
}
Try this, And for generic method the method definition you have used is not correct.
It should be
//MethodName<T,U>(T para1, U para2)
I have change the code to include reflections, this should work.
Please try and give feedback.
using System;
using System.Collections.Generic;
using System.Reflection;
namespace test
{
class MainClass
{
public static List<Mycapsule<int, double>> sample = new List<Mycapsule<int, double>>();
public static void Main(string[] args)
{
sample.Add(new Mycapsule<int, double> { id = 1, value = 1.2 });
update(pred, 12.3);
}
public static bool pred(double x)
{
if (x == 2.5) return true;
return false;
}
public static bool update<T>(Func<T, bool> predicate, T i)
{
var myCollection = sample.FindAll(p => pred(JustValue<double>(p)));
MainClass mainClass = new MainClass();
foreach (var x in myCollection)
{
MethodInfo changeTypeMethod = typeof(MainClass).GetMethod("GetValue");
object value = changeTypeMethod.Invoke(mainClass, new object[] { i, typeof(T) });
PropertyInfo valueProperty = x.GetType().GetProperty("value");
valueProperty.SetValue(x, value);
}
return true;
}
public T GetValue<T>(T i)
{
return (T)Convert.ChangeType(i, typeof(T));
}
public static T JustValue<T>(Mycapsule<int, T> i)
{
return i.value;
}
}
//Outside the MainClass inside the same namespace
public class Mycapsule<KT, T>
{
public KT id { get; set; }
public T value { get; set; }
public int p; // and more
}
}

Passing around member functions in C#

Mostly it comes handy that C# delegates already store the object together with the member function. But is there a way, to store -- and pass as parameters -- only the member function itself, just as the good old pointer-to-member-function in C++?
In case the description is less than clear, I give a self-contained example. And, yes, in the example the insistence to pass around member functions is totally pointless, but I have more serious uses for this.
class Foo {
public int i { get; set; }
/* Can this be done?
public static int Apply (Foo obj, ???? method, int j) {
return obj.method (j);
}
*/
public static int ApplyHack (Foo obj, Func<int, int> method, int j) {
return (int) method.Method.Invoke (obj, new object [] { j });
}
public static readonly Foo _ = new Foo (); // dummy object for ApplyHack
public int Multiply (int j) {
return i * j;
}
public int Add (int j) {
return i + j;
}
}
class Program {
static void Main (string [] args) {
var foo = new Foo { i = 7 };
Console.Write ("{0}\n", Foo.ApplyHack (foo, Foo._.Multiply, 5));
Console.Write ("{0}\n", Foo.ApplyHack (foo, Foo._.Add, 5));
Console.ReadKey ();
}
}
You see, the only workaround I've found is rather ugly and probably slow.
What you want is something called an open instance delegate. I've written about them on my blog
Basically, you can create a delegate to an instance method without tying it to a particular instance, and specify the instance to use it on when you call it:
class Foo {
public int i { get; set; }
public int Multiply (int j) {
return i * j;
}
public int Add (int j) {
return i + j;
}
}
class Program {
static void Main (string [] args) {
Func<Foo, int, int> multiply = (Func<Foo, int, int>)Delegate.CreateDelegate(typeof(Func<Foo, int, int>), null, typeof(Foo).GetMethod("Multiply");
Func<Foo, int, int> add = (Func<Foo, int, int>)Delegate.CreateDelegate(typeof(Func<Foo, int, int>), null, typeof(Foo).GetMethod("Add");
var foo1 = new Foo { i = 7 };
var foo2 = new Foo { i = 8 };
Console.Write ("{0}\n", multiply(foo1, 5));
Console.Write ("{0}\n", add(foo1, 5));
Console.Write ("{0}\n", multiply(foo2, 5));
Console.Write ("{0}\n", add(foo2, 5));
Console.ReadKey ();
}
}
Taking your existing code:
public static int ApplyHack (Foo obj, Func<int, int> method, int j) {
return (int) method.Method.Invoke (obj, new object [] { j });
}
You could do something like this:
public static int ApplyHack (Foo obj, Func<int, int> method, int j) {
var func = (Func<int,int>)Delegate.CreateDelegate(typeof(Func<int,int>), obj, method.Method);
return func(j);
}
This will create a new delegate around the method and the new object. To take your first example:
public static int Apply (Foo obj, ???? method, int j) {
return obj.method (j);
}
The type you are looking for is System.Reflection.MethodInfo and it would look like this:
public static int Apply (Foo obj, MethodInfo method, int j) {
var func = (Func<int,int>)Delegate.CreateDelegate(typeof(Func<int,int>), obj, method);
return func(i);
}
Note that while you are allocating delegates for each invocation, I believe this will still be faster than using reflection, since you do not have to box function input/output, nor store it in object[] arrays.
Assuming you're using C# 2.0 or above, and have access to anonymous delegates, you can do it very simply by wrapping the function in an anonymous delegate at the point of storage:
class Foo
{
public Foo(int v)
{
this.v = v;
}
int v;
public int Multiply(int x)
{
return v * x;
}
public int Add(int x)
{
return v+x;
}
delegate int NewFunctionPointer(Foo, int);
delegate int OldDelegateStyle(int);
static void Example()
{
Foo f = new Foo(2);
Foo f2 = new Foo(3);
// instead of this, which binds an instance
OldDelegateStyle oldMul = f.Multiply;
// You have to use this
NewFunctionPointer mul = delegate(Foo f, int x) { return f.Multiply(x); }
NewFunctionPointer add = delegate(Foo f, int x) { return f.Add(x); }
// But can now do this
mul(f, 4); // = 8
add(f2, 1); // = 3
}
}
If you're okay with passing the this reference as a parameter, why not just use static methods?
class Foo {
public int i;
public static int ApplyHack(Foo foo, Func<Foo, int, int> method, int j) {
return method(foo, j);
}
public static int Multiply(Foo foo, int j) {
return foo.i * j;
}
}
Console.Write("{0}\n", Foo.ApplyHack(foo, Foo.Multiply, 5));
This mainly affects how you construct the Foo object, without changing how you use it. It also doesn't prevent you from having a non-static int Multiply(int) method.
You could retrieve and reuse the MethodInfo for the method or just use the name and extract the method at runtime.
public static int ApplyHack (Foo obj, string methodName, int j)
{
var method = typeof(Foo).GetMethod(methodName);
return (int) method.Invoke (obj, new object [] { j });
}
I'd be very careful that this was actually necessary as it seems like a code smell to me.
You can do it that way
class Foo
{
public int i { get; set; }
public static int Apply(Foo obj, Func<int, int, int> method, int j)
{
return method(j, obj.i);
}
public static int Multiply(int j, int i)
{
return i * j;
}
public static int Add(int j, int i)
{
return i + j;
}
}
static void Main(string[] args)
{
var foo = new Foo { i = 7 };
Console.Write("{0}\n", Foo.Apply(foo, Foo.Multiply, 5));
Console.Write("{0}\n", Foo.Apply(foo, Foo.Add, 5));
Console.ReadKey();
}
I think you can do this easily with this if I understand correctly:
public static int Apply(Func<int, int> method, int j)
{
return (int)method.Method.Invoke(method.Target, new object[] { j });
}
and call it like this:
Console.Write("{0}\n", Foo.Apply(foo.Multiply, 5));

Categories

Resources