1

I want to create Extension methods for dynamic type, but for some or the other reason i get error while compiling the code. below is my code sample The method which i am using is

public List<State> getStates()
{

    return new List<State>(){
         new State{StateID="1",StateName="Tamil Nadu"},
         new State{StateID="2",StateName="Assam"},
         new State{StateID="3",StateName="Andra"},
         new State{StateID="4",StateName="bihar"},
         new State{StateID="5",StateName="Bengal"},            
    };
}

and my extension method is

public static class helper
{
     public static IEnumerable<SelectListItem> getIntoDropDownState(this List<dynamic> data,string textField,string valueField)
    {
        return data.Select(x => new SelectListItem
        {
            Text = x.textField,
            Value = x.valueField
        });
    }
}

My compilation error which i get is

Compiler Error Message: CS1928: 'System.Collections.Generic.List' does not contain a definition for 'getIntoDropDownState' and the best extension method overload 'LearnAuthentication.Controllers.helper.getIntoDropDownState(System.Collections.Generic.List, string, string)' has some invalid arguments

I want to use the Extension method like this, and I am facing error

 @Html.DropDownListFor(x => x.StateID, new LearnAuthentication.Controllers.Address().getStates().getIntoDropDownState("StateName", "StateID"), "Select State", 0)

can anyone help

Nkosi
  • 235,767
  • 35
  • 427
  • 472
Lijin Durairaj
  • 4,910
  • 15
  • 52
  • 85

2 Answers2

1

Dynamic types in extension methods is not supported. Cast the dynamic types to actual types, and it will work. For more details check the below URL, Extension methods cannot be dynamically dispatched

Community
  • 1
  • 1
prabhu379
  • 69
  • 3
1

That extension method in your example is not going to do what you describe. You could use reflection and generics.

public static class helper {
    public static IEnumerable<SelectListItem> getIntoDropDownState<T>(this List<T> data, string textField, string valueField) where T : class {
        var type = typeof(T);

        var textPropertyInfo = type.GetProperty(textField);
        var valuePropertyInfo = type.GetProperty(valueField);

        return data.Select(x => new SelectListItem {
            Text = (string)textPropertyInfo.GetValue(x),
            Value = (string)valuePropertyInfo.GetValue(x)
        });
    }
}

Here is a unit test for the extension method

[TestClass]
public class MyTestClass {
    [TestMethod]
    public void MyTestMethod() {
        //Arrange
        var data = getStates();

        //Act
        var result = data.getIntoDropDownState("StateName", "StateID");

        //Assert
        Assert.IsNotNull(result);
        var first = result.First();
        Assert.AreEqual(data[0].StateName, first.Text);
        Assert.AreEqual(data[0].StateID, first.Value);
    }

    public List<State> getStates() {

        return new List<State>(){
             new State{StateID="1",StateName="Tamil Nadu"},
             new State{StateID="2",StateName="Assam"},
             new State{StateID="3",StateName="Andra"},
             new State{StateID="4",StateName="bihar"},
             new State{StateID="5",StateName="Bengal"},            
        };
    }

    public class State {
        public string StateID { get; set; }
        public string StateName { get; set; }
    }
}

Or you could forego reflection and use System.Web.Mvc.SelectList which does the heavy reflection lifting for you

public static class helper {
    public static IEnumerable<System.Web.Mvc.SelectListItem> getIntoDropDownState<T>(this List<T> data, string textField, string valueField) where T : class {

        return new System.Web.Mvc.SelectList(data, valueField, textField);

    }
}
Nkosi
  • 235,767
  • 35
  • 427
  • 472
  • i guess this is the only way we can make it possible. thank you for the time. I actually wanted to create a method by calling which a dropdown could be easily get bind in MVC – Lijin Durairaj Aug 25 '16 at 17:51