Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Which is better Params or List

Tags:

c#

.net

My current code is following, it is a WCF service method exposed as a proxy to the client:

public UnifiedDTO GetAllCardTitle(string trainSymbolOrCarLocation, 
                                  DateTime startDate, 
                                  DateTime endDate, 
                                  string procedureName = CardTitle.procedureNameTrainRuns)

This method takes a procedure name (as the last parameter) and rest of the parameters are the binding the input parameters, however the issue is that we do not have the flexibility in the case of parameters numbers and types changing. The project is in its initial stage, so changes will surely be made.

The options that I have is convert the method as follows:

public UnifiedDTO GetAllCardTitle(params object [] parameters)

Where we have the freedom to pass the parameters and procedure details and can accordingly bind. However, there might be a performance issue due to boxing and unboxing. It would require client application to pass the parameters with correct order and value to bind as it would be expected by underlying layers

public UnifiedDTO GetAllCardTitle(List<Filter> parameter, string procedureName)

Where Parameter class would be defined as:

public class Filter
{
    public string name { set; get; }
    public string value { set; get; }
    public string dataTypeID { set; get; }

    public Filter(string _name, string _value, string _dataTypeID)
    {
        name = _name;
        value = _value;
        dataTypeID = _dataTypeID;
    }
}

In this method for a given procedure, we bind each parameter with its name value and DataType, and it would need value to typecasted to the correct data type, it has more flexibility then last method and can be passed in any order, as binding is by name. However, it would need much more due diligence from the application.

Is there still a better way to take care of this situation using something new introduced in C#.Net?

like image 208
Mrinal Kamboj Avatar asked Apr 29 '14 07:04

Mrinal Kamboj


People also ask

When should I use params?

By using the params keyword, you can specify a method parameter that takes a variable number of arguments. The parameter type must be a single-dimensional array. No additional parameters are permitted after the params keyword in a method declaration, and only one params keyword is permitted in a method declaration.

What params means?

What Does Parameter (param) Mean? A parameter is a special kind of variable in computer programming language that is used to pass information between functions or procedures. The actual information passed is called an argument.

What is params params?

Params is an important keyword in C#. It is used as a parameter which can take the variable number of arguments. Important Point About Params Keyword : It is useful when programmer don't have any prior knowledge about the number of parameters to be used.

What does params mean in C#?

The "params" keyword in C# allows a method to accept a variable number of arguments. C# params works as an array of objects. By using params keyword in a method argument definition, we can pass a number of arguments.


2 Answers

None. Use Dynamic object instead

To create a C# class that works with the DLR, the easiest thing to do is derive from DynamicObject. One limitation arises when trying to use a dynamic type in a WCF service. Trying to use a DynamicObject-derived type will result in a runtime exception when trying to serialize with WCF’s DataContractSerializer.

[DataContract]
public class SerializableDynamicObject : IDynamicMetaObjectProvider
{
[DataMember]
private IDictionary<string,object> dynamicProperties = new Dictionary<string,object>();

#region IDynamicMetaObjectProvider implementation
public DynamicMetaObject GetMetaObject (Expression expression)
{
    return new SerializableDynamicMetaObject(expression, 
        BindingRestrictions.GetInstanceRestriction(expression, this), this);
}
#endregion

#region Helper methods for dynamic meta object support
internal object setValue(string name, object value) 
{
    dynamicProperties.Add(name, value);
    return value;
}

internal object getValue(string name) 
{
    object value;
    if(!dynamicProperties.TryGetValue(name, out value)) {
        value = null;
    }
    return value;
}

internal IEnumerable<string> getDynamicMemberNames() 
{
    return dynamicProperties.Keys;
}
#endregion
}


public class SerializableDynamicMetaObject : DynamicMetaObject
{
Type objType;

public SerializableDynamicMetaObject(Expression expression, BindingRestrictions restrictions, object value) 
    : base(expression, restrictions, value) 
{
    objType = value.GetType();
}

public override DynamicMetaObject BindGetMember (GetMemberBinder binder)
{
    var self = this.Expression;
    var dynObj = (SerializableDynamicObject)this.Value;
    var keyExpr = Expression.Constant(binder.Name);
    var getMethod = objType.GetMethod("getValue", BindingFlags.NonPublic | BindingFlags.Instance);
    var target = Expression.Call(Expression.Convert(self, objType),
                                 getMethod,
                                 keyExpr);
    return new DynamicMetaObject(target,
        BindingRestrictions.GetTypeRestriction(self, objType));
}

public override DynamicMetaObject BindSetMember (SetMemberBinder binder, DynamicMetaObject value)
{
    var self = this.Expression;
    var keyExpr = Expression.Constant(binder.Name); 
    var valueExpr = Expression.Convert(value.Expression, typeof(object));
    var setMethod = objType.GetMethod("setValue", BindingFlags.NonPublic | BindingFlags.Instance);
    var target = Expression.Call(Expression.Convert(self, objType),
    setMethod, 
    keyExpr, 
    valueExpr);
    return new DynamicMetaObject(target,
        BindingRestrictions.GetTypeRestriction(self, objType));
}

public override IEnumerable<string> GetDynamicMemberNames ()
{
    var dynObj = (SerializableDynamicObject)this.Value;
    return dynObj.getDynamicMemberNames();
}
}

One warning, dynamic members can be anything, meaning at runtime someone could assign a method to one of these fields. If this is possible in your application, you’ll need to ensure any methods assigned to the dynamic type are not serialized. I’m leaving this as an exercise for the reader.

Taken from Here

like image 92
Matas Vaitkevicius Avatar answered Oct 07 '22 18:10

Matas Vaitkevicius


Is it possible to allow an "Interfaced" parameter. From that, you could handle multiple things based on the interfaced value setting. Just shooting out a simple sample.

public enum eWhatAmI
{
   ListedObjects,
   StringArrays,
   Other   
}

public interface IWhatParmType
{
   eWhatAmI whatAmI { get; set; }
}

public class MyListVersion : IWhatParmType
{
   public eWhatAmI whatAmI { get; set; }
   public List<string> whatever { get; set; }

   public MyListVersion()
   {
      whatAmI = eWhatAmI.ListedObjects;
      whatever = new List<string>();
      ... build out list of strings
   }
}

public class MyArrayVersion : IWhatParmType
{
   public eWhatAmI whatAmI { get; set; }
   public string[] whatever { get; set; }

   public MyArrayVersion()
   {
      whatAmI = eWhatAmI.StringArrays;
      ... build out array of strings
   }
}

etc...

Then in your process for handling whatever the incoming parameter is, you can handle either way.

public UnifiedDTO GetAllCardTitle(IWhatParmType parameter, string procedureName)
{
   switch( parameter )
   {
      case (eWhatAmI.ListedObjects):
         // Just for grins, test to make sure object really IS expected list version object
         if( parameter is MyListVersion)
            DoViaList( (MyListVersion)parameter );
         break;

      case (eWhatAmI.StringArrays ):
         if( parameter is MyArrayVersion )
            DoViaArray( (MyArrayVersion)parameter );
         break;
   }
}

private void DoViaList( MyListVersion parm1 )
{
   .. do whatever based on the "List<string>" property
}

private void DoViaArray( MyArrayVersion parm1 )
{
   .. do whatever based on the "string []" property
}

Then, if you ever needed to expand a setting per a particular object instance, you could and handle within the specific sub-handler method for populating or forcing whatever defaults to be implied.

like image 38
DRapp Avatar answered Oct 07 '22 19:10

DRapp