C# js-like spread (or triple dot) operator [duplicate] - c#

Is there any implementation in C# like JavaScript's spread syntax?
var arr = new []{
"1",
"2"//...
};
Console.WriteLine(...arr);

There isn't a spread option. And there are reasons.
Method Parameters aren't an array in C# unless you use the params keyword
Method Parameters that use the param keyword would have to either:
Share the same type
Have a castable shared type such as double for numerics
Be of type object[] (as object is the root type of everything)
However, having said that, you can get similar functionality with various language features.
Answering your example:
C#
var arr = new []{
"1",
"2"//...
};
Console.WriteLine(string.Join(", ", arr));
The link you provide has this example:
Javascript Spread
function sum(x, y, z) {
return x + y + z;
}
const numbers = [1, 2, 3];
console.log(sum(...numbers));
// expected output: 6
console.log(sum.apply(null, numbers));
Params
In C#, with same type
public int Sum(params int[] values)
{
return values.Sum(); // Using linq here shows part of why this doesn't make sense.
}
var numbers = new int[] {1,2,3};
Console.WriteLine(Sum(numbers));
In C#, with different numeric types, using double
public int Sum(params double[] values)
{
return values.Sum(); // Using linq here shows part of why this doesn't make sense.
}
var numbers = new double[] {1.5, 2.0, 3.0}; // Double usually doesn't have precision issues with small whole numbers
Console.WriteLine(Sum(numbers));
Reflection
In C#, with different numeric types, using object and reflection, this is probably the closest to what you are asking for.
using System;
using System.Reflection;
namespace ReflectionExample
{
class Program
{
static void Main(string[] args)
{
var paramSet = new object[] { 1, 2.0, 3L };
var mi = typeof(Program).GetMethod("Sum", BindingFlags.Public | BindingFlags.Static);
Console.WriteLine(mi.Invoke(null, paramSet));
}
public static int Sum(int x, double y, long z)
{
return x + (int)y + (int)z;
}
}
}

One trick to get a behavior similar to this (without reflection) is to accept params SomeObject[][] and to also define an implicit operator from SomeObject to SomeObject[]. Now you can pass a mixture of arrays of SomeObject and individual SomeObject elements.
public class Item
{
public string Text { get; }
public Item (string text)
{
this.Text = text;
}
public static implicit operator Item[] (Item one) => new[] { one };
}
public class Print
{
// Accept a params of arrays of items (but also single items because of implicit cast)
public static void WriteLine(params Item[][] items)
{
Console.WriteLine(string.Join(", ", items.SelectMany(x => x)));
}
}
public class Test
{
public void Main()
{
var array = new[] { new Item("a1"), new Item("a2"), new Item("a3") };
Print.WriteLine(new Item("one"), /* ... */ array, new Item("two"));
}
}

there is no direct pre-built library in C# to handle what is built into Spread
In order to get that functionality in C#, you need to Reflect the object and get the methods, properties, or fields by their access modifiers.
You'd do something like:
var tempMethods = typeof(myClass).GetMethods();
var tempFields = typeof(myClass).GetFields();
var tempProperties = typeof(myClass).GetProperties();
then iterate through and throw them into your dynamic object:
using System;
using System.Collections.Generic;
using System.Dynamic;
namespace myApp
{
public class myClass
{
public string myProp { get; set; }
public string myField;
public string myFunction()
{
return "";
}
}
class Program
{
static void Main(string[] args)
{
var fields = typeof(myClass).GetFields();
dynamic EO = new ExpandoObject();
foreach (int i = 0; i < fields.Length; i++)
{
AddProperty(EO, "Language", "lang" + i);
Console.Write(EO.Language);
}
}
public static void AddProperty(ExpandoObject expando, string propertyName, object propertyValue)
{
// ExpandoObject supports IDictionary so we can extend it like this
var expandoDict = expando as IDictionary<string, object>;
if (expandoDict.ContainsKey(propertyName))
expandoDict[propertyName] = propertyValue;
else
expandoDict.Add(propertyName, propertyValue);
}
}
}
https://www.oreilly.com/learning/building-c-objects-dynamically

you can also do the following
var a = new List<int>(new int[]{1,2,3}){5};
Console.WriteLine(a.Count);
will print 4
if you want to achieve initialization of lists or arrays with both an accompanying enumerable and parameters

Related

Is it possible to pass List elements as arguments for methods in C#? [duplicate]

Is there any implementation in C# like JavaScript's spread syntax?
var arr = new []{
"1",
"2"//...
};
Console.WriteLine(...arr);
There isn't a spread option. And there are reasons.
Method Parameters aren't an array in C# unless you use the params keyword
Method Parameters that use the param keyword would have to either:
Share the same type
Have a castable shared type such as double for numerics
Be of type object[] (as object is the root type of everything)
However, having said that, you can get similar functionality with various language features.
Answering your example:
C#
var arr = new []{
"1",
"2"//...
};
Console.WriteLine(string.Join(", ", arr));
The link you provide has this example:
Javascript Spread
function sum(x, y, z) {
return x + y + z;
}
const numbers = [1, 2, 3];
console.log(sum(...numbers));
// expected output: 6
console.log(sum.apply(null, numbers));
Params
In C#, with same type
public int Sum(params int[] values)
{
return values.Sum(); // Using linq here shows part of why this doesn't make sense.
}
var numbers = new int[] {1,2,3};
Console.WriteLine(Sum(numbers));
In C#, with different numeric types, using double
public int Sum(params double[] values)
{
return values.Sum(); // Using linq here shows part of why this doesn't make sense.
}
var numbers = new double[] {1.5, 2.0, 3.0}; // Double usually doesn't have precision issues with small whole numbers
Console.WriteLine(Sum(numbers));
Reflection
In C#, with different numeric types, using object and reflection, this is probably the closest to what you are asking for.
using System;
using System.Reflection;
namespace ReflectionExample
{
class Program
{
static void Main(string[] args)
{
var paramSet = new object[] { 1, 2.0, 3L };
var mi = typeof(Program).GetMethod("Sum", BindingFlags.Public | BindingFlags.Static);
Console.WriteLine(mi.Invoke(null, paramSet));
}
public static int Sum(int x, double y, long z)
{
return x + (int)y + (int)z;
}
}
}
One trick to get a behavior similar to this (without reflection) is to accept params SomeObject[][] and to also define an implicit operator from SomeObject to SomeObject[]. Now you can pass a mixture of arrays of SomeObject and individual SomeObject elements.
public class Item
{
public string Text { get; }
public Item (string text)
{
this.Text = text;
}
public static implicit operator Item[] (Item one) => new[] { one };
}
public class Print
{
// Accept a params of arrays of items (but also single items because of implicit cast)
public static void WriteLine(params Item[][] items)
{
Console.WriteLine(string.Join(", ", items.SelectMany(x => x)));
}
}
public class Test
{
public void Main()
{
var array = new[] { new Item("a1"), new Item("a2"), new Item("a3") };
Print.WriteLine(new Item("one"), /* ... */ array, new Item("two"));
}
}
there is no direct pre-built library in C# to handle what is built into Spread
In order to get that functionality in C#, you need to Reflect the object and get the methods, properties, or fields by their access modifiers.
You'd do something like:
var tempMethods = typeof(myClass).GetMethods();
var tempFields = typeof(myClass).GetFields();
var tempProperties = typeof(myClass).GetProperties();
then iterate through and throw them into your dynamic object:
using System;
using System.Collections.Generic;
using System.Dynamic;
namespace myApp
{
public class myClass
{
public string myProp { get; set; }
public string myField;
public string myFunction()
{
return "";
}
}
class Program
{
static void Main(string[] args)
{
var fields = typeof(myClass).GetFields();
dynamic EO = new ExpandoObject();
foreach (int i = 0; i < fields.Length; i++)
{
AddProperty(EO, "Language", "lang" + i);
Console.Write(EO.Language);
}
}
public static void AddProperty(ExpandoObject expando, string propertyName, object propertyValue)
{
// ExpandoObject supports IDictionary so we can extend it like this
var expandoDict = expando as IDictionary<string, object>;
if (expandoDict.ContainsKey(propertyName))
expandoDict[propertyName] = propertyValue;
else
expandoDict.Add(propertyName, propertyValue);
}
}
}
https://www.oreilly.com/learning/building-c-objects-dynamically
you can also do the following
var a = new List<int>(new int[]{1,2,3}){5};
Console.WriteLine(a.Count);
will print 4
if you want to achieve initialization of lists or arrays with both an accompanying enumerable and parameters

Implement class to work with real time data

Using C# I need to transform a time series, for example:
Input: 1 2 1 0 3 2 -> Output: 1 3 4 4 7 9
In the previous example an output is the sum of current input with the previous inputs.
I will have different transformations so I started with an abstract class:
public abstract class Transformation<TInput, TOutput> {
private IEnumerable<TInput> _inputs { get; set; }
public Transformation(IEnumerable<TInput> inputs) {
_inputs = inputs;
}
public abstract IEnumerable<TOutput> Calculate();
}
So a transformation would be something like:
public class TransformationOne<Int32, Int32> {
public override IEnumerable<Int32> Calculate();
// Calculate the outputs with all inputs
}
}
This works fine if I have all inputs and want all outputs.
But sometimes I would like to use my class in real time.
So I would feed with a new input and would get a new output.
What would be the best way to implement this?
Keep the state in the class and send the input to the Calculate method?
class TransformationOne
{
private int _currentResult;
public int Calculate(int value)
{
_currentResult += value;
return _currentResult;
}
}
so you could do:
var transformationOne = new TransformationOne();
var inputs = new List<int> {1, 2, 1, 0, 3, 2};
foreach (var input in inputs)
{
var newResult = transformationOne.Calculate(input);
Console.WriteLine(newResult); // results: 1 3 4 4 7 9
}
Demo
My answer is very similar to what #Julian did. However, I had already written my solution, I think it does a better job of providing the two aspects of the OP's question:
How to do this for a sequence of data (like what was originally shown)
How do use the same capability for one-at-a-time data
You can't easily do this with a generic, there is no way to constrain a type to one that includes addition (if you know of one, let me now). So this is what the transformation class looks like:
public class AccumulateTransformer
{
private int currentState = 0;
public void Clear()
{
currentState = default(int);
}
public int NextValue(int input)
{
currentState += input;
return currentState;
}
public int Current => currentState;
public IEnumerable<int> TransformSequence(IEnumerable<int> inputs, bool clearFirst = true)
{
if (clearFirst)
{
Clear();
}
foreach (var value in inputs)
{
yield return NextValue(value);
}
}
}
And here's some code to test it (using your data):
var transformer = new AccumulateTransformer();
var inputs = new[] {1, 2, 1, 0, 3, 2,};
var results = transformer.TransformSequence(inputs);
Debug.WriteLine(string.Join(", ", from result in results select result.ToString() ));
transformer.Clear();
Debug.WriteLine(transformer.NextValue(1));
Debug.WriteLine(transformer.NextValue(2));
Debug.WriteLine(transformer.NextValue(1));
Debug.WriteLine(transformer.NextValue(0));
Debug.WriteLine(transformer.NextValue(3));
Debug.WriteLine(transformer.NextValue(2));
The output of that looks like:
1, 3, 4, 4, 7, 9
1
3
4
4
7
9
To make this generic, you need a way of doing the accumulation operation that isn't dependent on T understanding addition. To do that, change the code to what's show below.
It makes the type generic on T (which would be int in this case), but includes a constructor that takes a Func<T, T, T> that will do the accumulation. When you construct your instance, you provide a Func that just adds two numbers.
The class code:
public class AccumulateTransformer<T>
{
private T _currentState = default(T);
private Func<T, T, T> _accumulator;
public AccumulateTransformer(Func<T, T, T> accumulator)
{
_accumulator = accumulator;
}
public void Clear()
{
_currentState = default(T);
}
public T NextValue(T input)
{
_currentState = _accumulator(_currentState, input);
return _currentState;
}
public T Current => _currentState;
public IEnumerable<T> TransformSequence(IEnumerable<T> inputs, bool clearFirst = true)
{
if (clearFirst)
{
Clear();
}
foreach (var value in inputs)
{
yield return NextValue(value);
}
}
The only difference in using this is that you have to provide that accumulate Func in the constructor:
var transformer = new AccumulateTransformer<int>((a, b) => a + b);
Otherwise, it's used the same way and produces the same output.
I'm not sure if this is exactly what you're after, but you could simply keep a list of the items in the class, and provide public methods for adding new items to it:
public class Transformer
{
private readonly List<int> items = new List<int>();
public IEnumerable<int> Items => items.ToList();
public void Add(int item) => items.Add(items.LastOrDefault() + item);
public void Add(IEnumerable<int> input)
{
foreach (var item in input) Add(item);
}
public override string ToString()
{
return string.Join(", ", Items);
}
}
In use it might look like:
public static void Main(string[] args)
{
var trans = new Transformer();
var items = new[] { 1, 2, 1, 0, 3 };
// Add a bunch of inputs at once:
trans.Add(items);
// Display results
Console.WriteLine($"After adding 5 items: {trans}");
// Add a single item
trans.Add(2);
// Display results
Console.WriteLine($"After adding 1 more item: {trans}");
GetKeyFromUser("\nDone! Press any key to exit...");
}
Output
A simple Linq.Select() would do that:
int sum = 0;
var result = input.Select(x => { sum += x; return sum; });
Live Demo

Can you get a value in a structure through an outside variable in C#?

So, I am kind of used to structuring things like JavaScript and in light of that I do struggle in some areas in C#. Right now I'm trying to use structures in a way I can call a value using a variable that would match the value I'm going for.
For example my structure would be this:
public struct test
{
public int[] valuesOne;
public int[] valuesTwo;
public test(int[] data)
{
valuesOne = new int[2] { data[0], data[1] };
valuesTwo = new int[2] { data[2], data[3] };
}
}
Okay so say I have all of this and I want to get test.valuesOne[0] but from a variable like so:
string getValue = "valuesOne";
Console.Log(test[getValue][0]);
I know this provides a indexing error, but I'm in a situation where I kind of want this functionality. Sure I can pass my structure through a simple method, but if I can do it in a similar way to this without a huge problem I'd like to.
c# and JavaScript are two different pairs of shoes.
I try to do something similar as your code, however not sure if that's what you're looking for.
class Program
{
static void Main(string[] args)
{
var t = new Test(new int[] { 1, 2, 3, 4 });
var value = t["valueOne"][0];
Console.WriteLine(value);
}
}
public class Test
{
private Dictionary<string, int[]> _data = new Dictionary<string, int[]>();
public Test(int[] data)
{
_data.Add("valueOne", new int[] { data[0], data[1]});
_data.Add("valueTwo", new int[] { data[2], data[3]});
}
public int[] this [string value]
{
get { return _data[value]; }
}
}
you can use dynamic + reflection + this[string key] to do it. but it needs some extra code.
note :
it's a bad idea,this will lose the advantage of strong type checking.
demo :
void Main()
{
var test = new test(new[] {1,2,3,4,5});
Console.WriteLine( test["valuesOne"][0] ); //1
Console.WriteLine( test["valuesTwo"][1] ); //4
}
public struct test
{
public int[] valuesOne;
public int[] valuesTwo;
public test(int[] data)
{
valuesOne = new int[2] { data[0], data[1] };
valuesTwo = new int[2] { data[2], data[3] };
}
public dynamic this[string key]
{
get
{
return this.GetFieldValue(key);
}
}
}
public static class Extension
{
public static object GetFieldValue(this object t, string fieldName)
{
var type = t.GetType();
var fields = type.GetFields();
var field = fields.Single(pi => pi.Name == fieldName);
return field.GetValue(t);
}
}
online demo link : can-you-get-a-value-in-a-structure-through-an-outside-variable-in-c | .NET Fiddle
Usually I too would recommend using a Dictionary as in #gsharp's answer. But since that isn't an option for you, perhaps you could go with a Dictionary of delegates instead:
var accessor = new Dictionary<string, Func<test, int[]>>
{
{ nameof(test.valuesOne), x => x.valuesOne },
{ nameof(test.valuesTwo), x => x.valuesTwo }
};
Now you can access your data like so:
string getValue = "valuesOne";
Console.Log(accessor[getValue](test_instance)[0]);
You can extend this concept by wrapping this Dictionary into an Extension Method:
public static class Extensions
{
private static new Dictionary<string, Func<test, int[]>> accessor =
new Dictionary<string, Func<test, int[]>>
{
{ nameof(test.valuesOne), x => x.valuesOne },
{ nameof(test.valuesTwo), x => x.valuesTwo }
};
public static int[] Property(this test t, string name)
{
return accessor[name](t);
}
}
Then you can write:
Console.Log(test_instance.Property(getValue)[0]);

how to make generic method having List<dto> paramter for method c#

Need to create generic method which will accept List<child1> and List<child2>.
public class Parent
{
public string Name { get; set; }
public decimal ProductRate { get; set; }
}
public class Child1 : Parent
{
}
public class Child2 : Parent
{
}
Program : As shown below i am trying to to pass the values in method
public class HelloFriend
{
public static void Main(string[] args)
{
List<Child1> child1 = new List<Child1>()
{
new Child1(){ Name="Admin", ProductRate = 10}
};
List<Child2> child2 = new List<Child2>()
{
new Child2(){ Name="Admin", ProductRate = 50}
};
decimal result1 = getvalues(child1, 10);
decimal result2 = getvalues(child2, 10);
}
public static decimal getvalues(List<Child1> list, decimal calculateValue)
{
decimal value = 1;
if(parentList !=null )
{
foreach( var item in parentList)
{
value = item.ProductRate * 100 * calculateValue;
}
}
return value;
}
}
How to make getvalues() generics that will work with all List of Child1 and Chil2
A short console project to illustrate the use of generic types here:
[I used the object definitions of your question]
static void Main()
{
List<Child1> child1s = new List<Child1>()
{
new Child1() { Name="c11", ProductRate=1},
new Child1() { Name="c12", ProductRate=2}
};
List<Child2> child2s = new List<Child2>()
{
new Child2() { Name="c21", ProductRate=30},
new Child2() { Name="c21", ProductRate=60}
};
foreach (var retval in GetValues(child1s, 5))
System.Console.WriteLine(retval);
foreach (var retval in GetValues(child2s, 5))
System.Console.WriteLine(retval);
System.Console.ReadKey();
}
public static IEnumerable<decimal> GetValues<T>(List<T> items, decimal calculatedValue) where T : Parent
{
foreach (var item in items)
{
yield return (decimal)(item.ProductRate * 100 * calculatedValue);
}
}
The function is defined as List<T> where T is the generic type parameter. This parameter is further limited by where T : Parent to fit only on objects of type Parent or inherited types of it.
You can also get the type of the given instance by typeof(T) to differentiate if needed, but for this kind you should first read further into generics.
Another way is as in KYL3Rs answer described, to define the input parameter as IEnumerable<Parent>(in his answer List<Parent>). That way you need no generics, just inheritance and implicit casting. You need IEnumerable<T> here, otherwise a conversation isn't implicit and must be made by hand.
static void Main()
{
.....
foreach (var retval in GetValues(child1s, 5))
System.Console.WriteLine(retval);
foreach (var retval in GetValues(child2s, 5))
System.Console.WriteLine(retval);
System.Console.ReadKey();
}
public static IEnumerable<decimal> GetValues(IEnumerable<Parent> items, decimal calculatedValue)
{
foreach (var item in items)
{
yield return (decimal)(item.ProductRate * 100 * calculatedValue);
}
}
Please also note my return value of a list of items (IEnumerable<decimal>) and the yield return statement. I think your single return value after processing a list was a bug. And I use IEnumerable to make it clear I do not modify the given collection.
Basic knowledge about inheritance: use a list of Parent and declare the getters/setters you need in Parent (like you did).
public static decimal getvalues(List<Parent> list, decimal calculateValue)
{
}
As the comments said, usage: (use Parent as list type)
List<Parent> child1 = new List<Parent>()
{
new Child1(){ Name="Admin", ProductRate = 10}
};
decimal result1 = getvalues(child1, 10);
Alternative: (cast the child-list)
List<Child1> child1 = new List<Child1>()
{
new Child1(){ Name="Admin", ProductRate = 10}
};
decimal result1 = getvalues(child1.Cast<Parent>(), 10);

cannot infer type parameters using Func [duplicate]

This question already has answers here:
Why can't C# infer type from this seemingly simple, obvious case
(5 answers)
Closed 7 years ago.
A colleague wrote this extension method that I wanted to produce an example for:
namespace ExtensionMethods {
public static class MyExtensions {
public static Res MyAggregate<T, Res>(this IEnumerable<T> source, Func<Res, int, T, Res> f) {
var i = 0;
Res result = default(Res);
foreach (T x in source) {
result = f(result, i, x);
i++;
}
return result;
}
}
}
It creates a generic Aggregate method that also includes an index.
My example (that follows) takes a list of strings and joins the 1st letter from the first word, the 2nd from the second, etc..
namespace ExtensionMethods {
public class Program {
public static string OffsetChars(string x, int i, string y) {
return x + y[i];
}
static void Main(string[] args) {
List<string> test = new List<string>() { "hello", "there", "you" };
// get h from (h)ello, h from t(h)ere and u from yo(u) (hhu)
string result = test.MyAggregate<string, string>(OffsetChars);
Console.WriteLine(result);
Console.ReadKey();
}
}
}
My question is about this line (the important one):
string result = test.MyAggregate<string, string>(OffsetChars);
Without <string, string> there is an error that the types of arguments cannot be inferred from usage. My question(s):
Why cannot they be inferred? Is there something missing from my code that would enable them to be inferred?
I tested with an explicit delegate (follows) but the same error occurs:
namespace ExtensionMethods {
delegate string OffsetMethod(string x, int i, string y);
public class Program {
public static string OffsetChars(string x, int i, string y) {
return x + y[i];
}
static void Main(string[] args) {
List<string> test = new List<string>() { "hello", "there", "you" };
// get h from (h)ello, h from t(h)ere and u from yo(u) (hhu)
OffsetMethod myMethod = OffsetChars;
string result = test.MyAggregate(myMethod);
Console.WriteLine(result);
Console.ReadKey();
}
}
}
To summarize, I want to ensure that I haven't missed anything with my code and, assuming that I haven't, to understand why the parameter types cannot be inferred.
Your method is just a delegate and therefore does not have any generic type arguments that could be infered.
When you define OffsetChars as a generic Func, they can be infered just fine:
public static Func<string, int, string, string> OffsetChars = (x, i, y) =>
{
return x + y[i];
};
WERTZUI is right, because the delegate does not have any generic arguments, compiler cannot infer it, so you have se error.

Categories