Reputation: 321
I'm pretty sure there's a simple solution to my problem. However I'm not able to find it
Let's say I have a method which is defined as follows:
public bool Insert(string table, List<KeyValuePair<string, string>> fields) { }
Right now, I'm calling the function like this:
db.Insert("personen", new List<KeyValuePair<string, string>> {
new KeyValuePair<string, string>("firstname", "Dominic") });
Is there a way to shorten this infinitely long line? Just to be clear, I mean this part of the call:
new List<KeyValuePair<string, string>> {
new KeyValuePair<string, string>("firstname", "Dominic") }
In C++, for example, you could/would do it this way:
db.Insert("personen", {{"firstname", "Dominic"}});
This would be much better with several values:
db.Insert("personen", {
{ "firstname", "Test" },
{ "lastname", "Test 2" },
{ "address", "Teest" }
});
C# version: v4.0.30319 .Net version: 4.6.1
Upvotes: 2
Views: 3213
Reputation: 696
Try the ValueTuples-Syntax:
public bool Insert(string table, params ValueTuple<string, string>[] keyValuePairs) { }
Then you can call the function like this:
db.Insert("personen",
( "firstname", "Test" ),
( "lastname", "Test 2" ),
( "address", "Teest" )
);
Upvotes: 0
Reputation: 3789
You can use dictionary instead.
IDictionary<int, string> dict = new Dictionary<int, string>()
{
{1,"One"},
{2, "Two"},
{3,"Three"}
};
Upvotes: 0
Reputation: 11597
This implemetation proofs you can use a using <symbol>=<type>;
clause to reduce clutter without much impact on the rest of your code. You only need the lines with a // $$$
comment, the rest is just red tape to get things going. This compiles and runs on v4.x:
using System.Collections.Generic;
using K = System.Collections.Generic.KeyValuePair<string, string>; // $$$
public class MainClass
{
public static void Main(string[] args)
{
DBClass db;
db = new DBClass();
db.Insert("personen", new List<K> { // $$$
new K("firstname", "Dominic") // $$$
});
}
}
public class DBClass
{
public bool Insert(string name, List<KeyValuePair<string, string>> values)
{
// ...
return false;
}
}
The lightest version would be as follows, but it requires some help on the db
side. This reduces clutter completely as you can see in the Insert()
invocation:
using System.Collections.Generic;
public class MainClass
{
public static void Main(string[] args)
{
DBClass db;
db = new DBClass();
db.Insert("personen",
"firstname", "Dominic",
"lastname", "Cinimod"
);
}
}
public class DBClass
{
public bool Insert(string name, params string[] values)
{
if (values.Length % 2 == 1)
{
throw new System.ArgumentException("wrong number of arguments");
}
// ...
}
}
I want to be a little more clear about the second solution because it is highly controversial. After the parity check you should package the values in KVPs:
if (values.Length % 2 == 1)
{
throw new System.ArgumentException("wrong number of arguments");
}
KVPs = new List<KeyValuePairs<string, string>>();
for (i = 0; i < values.Length; i += 2)
{
KVPs.Add(new KeyValuePair<string, string>(values[i], values[i + 1]));
}
With this done, just delegate to the original method:
return this.Insert(name, KVPs); // pass on the returned bool!
By having both overloads you can use either. The unstructured version has less clutter in code but cannot be statically checked. You need to run the code to see at runtime if it throws the exception or it runs smoothly. Because of this, it actually is "uglier" from a C# perspective, where strong typing tries hard to leverage static dependencies so that compiletime checks are possible.
Upvotes: 1
Reputation: 445
I think a mix of static factories and params is as close as you are going to get:
static bool Insert(string table, params KeyValuePair<string, string>[] fields) {...}
class KeyValueFactory
{
public static KeyValuePair<TKey, TValue> of<TKey, TValue>(TKey key, TValue value)
{
return new KeyValuePair<TKey, TValue>(key, value);
}
}
Example usage:
Insert(
"personen",
KeyValueFactory.of("firstname", "Dominic"),
KeyValueFactory.of("lastName", "test2"));
Upvotes: 5