C#中的键值数组放入参数

Coming from PHP, I have never written C# before and I have encountered something like this in C#:

public string rule(string playerId, string action, params string[] optionalData){
...
}

and in PHP it is like this

public function rule($playerId, $action, $optionalData=array()){
...
}

In PHP I simply fill out the parameter for the $optionalData like this...

myVar->rule("123", "myAction", array('url'=>'review.com');

However in C# I am not sure how to fill the optionalData (params string[] optionalData) parameter as it is a key value parameter (like in the PHP example). My question is how do I create a key value array like the PHP that I created in my example and put into the parameter?

CoolClass cc = new CoolClass();
cc.rule("123", "myAction", ???);

I was searching google and was looking at dictionary and hashmaps etc but I am guessing it is an overkill or it does not work..

Many thanks!

When you were looking at dictionaries, you were definitely looking at the right facility.

If rule() in C# is in your own code, may I recommend changing the signature to:

public string rule(string playerId, string action, IDictionary<string, string> optionalData = new Dictionary<string, string>()){
...
}

What this allows you to do:

  • Operate on the values in optionalData the way that other C# programmers will expect.
  • The = new Dictionary<string, string>() part of the suggested method signature make the parameter truly optional. It will not be necessary when calling the method.
  • You can use IDictionary<T> methods to work with the data. Some syntax you should be somewhat familiar with (consider accessing by key optionalData["someString"].)

However, if rule() is not in your code, you would leave out the optionalData by simply omitting parameters. Examples of valid calls of the original C# method in your question:

  • rule("Bob", "load")
  • rule("Bob", "load", "url", "www.example.com") (In this case, optionalData[0].Equals("url", StringComparisonOptions.Ordinal) and optionalData[1].Equals("www.example.com", StringComparisonOptions.Ordinal) is true.

One thing to consider about the original method - keep in mind that rule("Bob", "load", 'url") is a valid call, and you would need to have a run-time check to make sure you had the right number of parameters. Another plus to using a Dictionary<TKey, TValue>. You may even consider writing an adapter method to the original rule(), if you can't change it.

You can use a Dictionary:

Dictionary<string,string[]>

or something like:

Dictionary<int, string[]>

I believe dictionary will work in your case.

You can use Dictionary <key_datatype, value_datatype> .

Example:

Your method definition here :

public string rule(string playerId, string action, Dictionary<string, string> optionalData){
...
}

Method call:

Dictionary<string, string> optionalData = new Dictionary<string, string>();
optionalData.Add("url", "review.com");

cc.rule("123", "myAction", optionalData);

Or

you can use DynamoObject to make it more easier to write:

    dynamic optionalData = new ExpandoObject();

//The token after the dynamoObject period will be the key to the assigned value.
    optionalData.url = "review.com";

    cc.rule("123", "myAction", optionalData);

Your method can get the key-value pairs like this:

public string rule(string playerId, string action, dynamic optionalData)
{
...

            foreach (var pair in (IDictionary<string, object>)optionalData)
            {
                if (group.Key == "url")
                {
                   Console.WriteLine(group.Value);
                }
                else if (group.Key == "post")
                {
                    Console.WriteLine(group.Value);
                }
            }
 }