Currently coding in C#, I wonder if there is a way to factor the code as presented below
Entity1 = GetByName("EntityName1");
Entity2 = GetByName("EntityName2");
Entity3 = GetByName("EntityName3");
The idea would be to get a single call in the code, factoring the code by placing the entities
and the strings
in a container and iterating on this container to get a single "GetByName()
" line. Is there a way to do this?
"Is there a way to prevent multiplecalls to the same method at the same time?" Debouncing will prevent multiple calls to qrDetectado from the client-side. Also, adding a lock on qrDetectado will prevent additional calls to qrDetectado while qrDetectado is being executed.
Yes method calls slow down the code execution a tiny little bit, if they a not inlined by the c#-compiler or the jit-compiler. However, unless your code runs in a loop and is executed a million times or so, you should really focus on producing clean, understandable and maintainable code.
Yes any function (user-defined or from a library) can be called any number of times from any function including itself(in case of user-defined, called recursion) except for the main function. But a function can only be defined once.
You can use LINQ:
var names=new[]{"EntityName1","EntityName2","EntityName3",.....};
var entities=names.Select(name=>GetByName(name)).ToArray();
Without ToArray
, Select
will return an IEnumerable that will be reevalueated each time you enumerate it - that is, GetByName
will be called each time you enumerate the enumerable.
ToArray()
or ToList
will create an array (or list) you can use multiple times.
You can also call ToDictionary
if you want to be able to access the entities by name:
var entities=names.ToDictionary(name=>name,name=>GetByName(name));
All this assumes that the entities don't already exist or that GetByName
has to do some significant work to retrieve them. If the entities exist you can simply put them in a Dictionary<String,Entity>
. If the entities have a Name
property you can use ToDictionary
to create the dictionary in one statement:
var entities=new []{entity1,entity2,entity3,...};
var entitiesDict=entities.ToDictionary(entity=>entity.Name,entity=>entity);
Do you mean something like the below (where entities
is the collection of Entity1
, Entity1
& Entity3
):
var results = entities.Select(e => GetByName(e.Name));
It depends on what you're looking for. If you need to set the variables in a single line, that won't work. You could play with reflection if you're dealing with fields or properties, but honestly that seems messier than what you've got already.
If the data-structure doesn't matter, and you just need the data and are able to play with it as you see so fit, I'd probably enumerate it into a dictionary. Of course, that's pretty tightly coupled to what you've got now, which looks like it's a fake implementation anyway.
If you want to do that, it's pretty straight-forward. It's your choice how you create the IEnumerable<string>
that's represented below as entityNames
. You could use an array initializer as I do, you could use a List<string>
that you build over time, you could even yield return
it in its own method.
var entityNames = new[] { "EntityName1", "EntityName2", "EntityName3" };
var dict = entityNames.ToDictionary(c => c, c => GetByName(c));
Then it's just a matter of checking those.
var entity1 = dict["EntityName1"];
Or enumerating over the dictionary.
foreach(var kvp in dict)
{
Console.WriteLine("{0} - {1}", kvp.Key, kvp.Value);
}
But realistically, it's hard to know whether that's preferable to what you've already got.
Ok, here is an idea.
You can declare this function.
IReadOnlyDictionary<string, T> InstantiateByName<T>(
Func<string, T> instantiator
params string[] names)
{
return names.Distinct().ToDictionary(
name => name,
name => instantiator(name))
}
which you could call like this,
var entities = InstantiateByName(
GetByName,
"EntityName1",
"EntityName2",
"EntityName3");
To push the over-engineering to the next level,
you can install the Immutable Collections package,
PM> Install-Package Microsoft.Bcl.Immutable
and modify the function slightly,
using Microsoft.Immutable.Collections;
IReadOnlyDictionary<string, T> InstantiateByName<T>(
Func<string, T> instantiator
params string[] names,
IEqualityComparer<string> keyComparer = null,
IEqualityComparer<T> valueComparer = null)
{
if (keyComparer == null)
{
keyComparer = EqualityComparer<string>.Default;
}
if (valueComparer == null)
{
valueComparer = EqualityComparer<T>.Default;
}
return names.ToImmutableDictionary(
name => name,
name => instantiator(name),
keyComparer,
valueComparer);
}
The function would be used in the exactly the same way. However, the caller is responsible for passing unique keys to the function but, an alternative equality comparer can be passed.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With