简体   繁体   中英

Write a Generic Method that references static generic collections?

I have to write a method that takes in as a parameter string,int,short,long,float, or double and then assigns a random value to that parameter and stores it in a static ConcurrentDictionary . Performance is a major constraint, so I don't want to go with a design that will sacrifice performance

Example:

public void StoreVal<T>(T val)
{
   //Check if the val is already in the respective dictionary

   //If not, then create a random value 

   //Store both values in the dictionary
}

I created a static ConcurrentDictionary for each of the datatypes that I'm expecting. The key issue I'm facing now is how do I reference correct collection type from within the generic method, without having to use a whole bunch of if/else statements?

UPDATE: I am using a ConcurrentDictionary because this method will be called by 8 threads (at least) and I have to ensure there is only one mapped value for passed parameter. Another constraint is that each data-type should have it's own mapping ie if 10 (int) -> 25 (int), then 10 (short) is not required to point to 25 (short) - that's why I created a separate ConcurrentDictionary for each datatype.

If performance is critical and if the set of possible input types limited and known, consider using functions overloading instead of a generic function :

public void StoreVal(int val) { // no if needed, you know which Dictionary to use }

public void StoreVal(float val) { // no if needed, you know which Dictionary to use }

public void StoreVal(double val) { // no if needed, you know which Dictionary to use }

// etc ... 

Other solutions will necessary make use of branching, casts, or some form of boxing, which will in any case degrade your performances.

You can simply call GetOrAdd to add the value if it is not already there:

private ConcurrentDictionary<object, object> dictionary;
public void StoreVal<T>(T val)
{
    dictionary.GetOrAdd(val, _ => ComputeRandomValue());
}

My advice is to create overloads for each of those types (int, long, short, float and double). They're all value types, and, as such, don't have any common ancestor.

This is why many of the methods you find throughout the Base Class Library offer these overloads.

Your method's signature, as it stands, will accept any kind of parameter, even though it can only handle a small subset of them. This breaks the principle of least surprise .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM