4

i have a Function with a lot of parameters how can do like this print all parmetrs Kay, Value

public string GetCompatibility(int MediaId, int ProductsTypId, string id, string PreviousURL, HttpRequestBase Request, int? Width, int? Height, int? CampaignID)
{
      foreach (param in.GetEnvironmentVariables())
                 Console.WriteLine("  {0} = {1}", param.Key, param.Value);
}

I'm sorry I did not explain well enough the question

Yitzhak Weinberg
  • 2,324
  • 1
  • 17
  • 21
  • 11
    So many arguments is mostly a sign of bad design. Does your method really do exactly *one* thing? You should consider to split arguments into objects that belong together and devide your code into several sub-methods. Anyway you can use a set of arguments using the `params`-keyword: `public string GetCompatibility(params object[] args)`. – MakePeaceGreatAgain Oct 10 '16 at 14:41
  • That's completely impossible. – SLaks Oct 10 '16 at 14:43
  • Maybe consider changing your set of arguments into properties of a class that is passed to the method? – juharr Oct 10 '16 at 14:43
  • I'm not professional enough, but I asked if it is possible – Yitzhak Weinberg Oct 10 '16 at 14:44
  • No. http://stackoverflow.com/questions/471693/using-reflection-to-get-method-name-and-parameters – L-Four Oct 10 '16 at 14:45
  • Short answer: Parameters is easy (`MethodBase.GetCurrentMethod().GetParameters().Select(pi => pi.Name)`); parameter *values* for the current call is tough. – 15ee8f99-57ff-4f92-890c-b56153 Oct 10 '16 at 14:46
  • @Oluwafemi That's not an answer to the question. – L-Four Oct 10 '16 at 14:47
  • As HimBromBeere suggests, if you pass an object into the method, you can run a foreach loop over each object, calling out the value of each property (e.g., objObject.Name, objObject.Address, objObject.Binding etc.). This supposes you know what the properties of the object are before hand and can delineate them as show above. If however, you don't know what properties objObject has, you'll need to use Reflection as Ed Plunkett suggests. – SRQ Coder Oct 10 '16 at 14:48
  • @L-Four Right. Thanks – Oluwafemi Oct 10 '16 at 14:48
  • OP, the *only* reasonable way to do this in C# is to copy and paste a list of calls: `Console.WriteLine($"{nameof(MediaId)}: {MediaId}");` etc. etc. and fix the names by hand in each one. It's a hassle, but you only have to do it once. All of the clever solutions people are suggesting involve compromising (or obliterating, in most cases) the usability of your method just to ease the purely *internal* problem of echoing the parameters. That's something you'd end up regretting. This is one of those things where you just have to suck it up. Every language has a few. – 15ee8f99-57ff-4f92-890c-b56153 Oct 10 '16 at 15:19
  • It's not a stupid question at all. I'd like to be able to do this myself. Upvoted. – 15ee8f99-57ff-4f92-890c-b56153 Oct 10 '16 at 15:20

2 Answers2

0

Mostly having so many parameters on a method shows that your method does too many things. You should consider to refactor it into smaller chunks of logic.

Anyway if you think your method already is as small as possible you should put all parameters into a single DTO:

public class ParamValues
{
    public int MediaId {get; set; }
    // ...

    public ParamValues(int MediaId, int ProductsTypId, string id, string PreviousURL, HttpRequestBase Request, int? Width, int? Height, int? CampaignID)
    {
        this.MediaId = MediaId;
        // ...
    }
}

Now in your calling code:

GetCompatibility(new ParamValues(...));

Now you can easily log all your parameters, either using reflection on the ParamValues-class (bad idea) or directly within the constructor of ParamValues.

Another way is using the params-keyword:

public string GetCompatibility(params object[] args)
{
    foreach(var arg in args) Console.WriteLine(arg);
}

However if you use this approach you´ll use the arguments names. Moreover you simply hide the complexity of the method, which is a bad design, so you should chose that opportunity as last resort.

MakePeaceGreatAgain
  • 35,491
  • 6
  • 60
  • 111
  • I don't see how that code smells any better than the original. If he wants to iterate through the parameters to *that* method, he can copy and paste. If he'll be changing the parameter list so often that that's impractical, he's got much bigger problems than how to enumerate the parameters. If he wants to iterate through the parameters to a dozen different methods, defining a dozen parameter classes is plain nuts. Obviously, though, this *is* a solution to his problem. Or the problem he thinks he has, anyway. – 15ee8f99-57ff-4f92-890c-b56153 Oct 10 '16 at 14:58
  • @EdPlunkett You´re right, obviosly the main-problem of the OP *is* a bad design. In this case you´re right that this answer won´t solve that problem. – MakePeaceGreatAgain Oct 10 '16 at 15:01
  • IMHO OP shouldn't even be told that `params` exists, he'll be using it everywhere and posting questions about why it says his int is a string or something. – 15ee8f99-57ff-4f92-890c-b56153 Oct 10 '16 at 15:01
  • @EdPlunkett Again you´re right, I added a comment for that. – MakePeaceGreatAgain Oct 10 '16 at 15:03
0

You can use a Dictionary to arrange your paramters.

public static void GetCompatibility(Dictionary<string, object> paramters)
{
    foreach (var pair in paramters)
        Console.WriteLine("  {0} = {1}", pair.Key, pair.Value);
}

//...
Dictionary<string, object> paramters = new Dictionary<string, object>
{
    {"MediaId", 1},
    {"ProductsTypId", 1},
    {"PreviousURL", "http://xxx"},
    {"Request", null},
    {"Width", 123},
    {"Height", 123},
    {"CampaignID", 123},
};
GetCompatibility(paramters);
//...

Or, if the paramters are fixed, use a struct to do that.

public struct CompatibilityParam
{
    public int MediaId;
    public int ProductsTypId;
    public string id;
    public string PreviousURL;
    public HttpRequestBase Request;
    public int? Width;
    public int? Height;
    public int? CampaignID;
}
public static void GetCompatibility(CompatibilityParam paramters)
{
    Console.WriteLine("  MediaId = {0}", paramters.MediaId);
    Console.WriteLine("  ProductsTypId= {0}", paramters.ProductsTypId);
    Console.WriteLine("  PreviousURL= {0}", paramters.PreviousURL);
    Console.WriteLine("  Request= {0}", paramters.Request);
    Console.WriteLine("  Width= {0}", paramters.Width);
    Console.WriteLine("  Height= {0}", paramters.Height);
    Console.WriteLine("  CampaignID= {0}", paramters.CampaignID);
}

//...
CompatibilityParam paramters = new CompatibilityParam
{
    MediaId = 1,
    ProductsTypId = 1,
    PreviousURL = "http://xxx",
    Request = null,
    Width = 123,
    Height = 123,
};
GetCompatibility(paramters);
//...
zwcloud
  • 4,546
  • 3
  • 40
  • 69