asawyer
asawyer

Reputation: 17808

implicitly convert type problem

I have the following classes:

public class DictionaryBuilder<T> where T : IDictionary<string, object>, new()
{
    private List<Tuple<string, object>> values_ = new List<Tuple<string, object>>();

    public DictionaryBuilder<T> WithValue(string key, object obj)
    {
        values_.Add(Tuple.Create(key, obj));
        return this;
    }
    public static implicit operator T(DictionaryBuilder<T> builder)
    {
        return builder.Build();
    }
    public T Build()
    {
        var dict = new T();
        foreach (var value in values_)
        {
            dict.Add(value.Item1, value.Item2);
        }
        return dict;
    }
}

public static class Admin
{
    public static string IndexPath { get { return "Admin/Index"; } }
    public static DictionaryBuilder<RouteValueDictionary> IndexRoute 
    { 
        get 
        { 
            return new DictionaryBuilder<RouteValueDictionary>()
                .WithValue("controller", "Admin")
                .WithValue("action", "Index"); 
        } 
    }
}

And it is used like:

@Html.RouteLink("Admim",
    Admin.IndexRoute
        .WithValue("id",3),
    new DictionaryBuilder<Dictionary<string,object>>()
        .WithValue("class","AdminRouteLink")

This is a bit of a mouthful, and the generics are obstructing the intent a little. I'd like to do this:

public class RouteValues : DictionaryBuilder<RouteValueDictionary> { }
public class HtmlValues : DictionaryBuilder<Dictionary<string,object>> { }

public static class Admin
{
    public static string IndexPath { get { return "Admin/Index"; } }
    public static RouteValues IndexRoute 
    { 
        get 
        { 
            return new RouteValues()
                .WithValue("controller", "Admin")
                .WithValue("action", "Index"); 
        } 
    }
}

@Html.RouteLink("Admim",
    Admin.IndexRoute
        .WithValue("id",3),
    new HtmlValues()
        .WithValue("class","AdminRouteLink")

Unfortunately, I'm getting a conversion error I'm afraid I don't fully understand:

Cannot implicitly convert type  
'ControllerActionExporter
    .DictionaryBuilder<System.Web.Routing.RouteValueDictionary>'    
to 
'ControllerActionExporter.RouteValues'. 
An explicit conversion exists (are you missing a cast?)  


        return new RouteValues()
            .WithValue("controller", "Admin")
            .WithValue("action", "Index"); //error occurs on this line

What am I doing wrong, and how do I correct the problem?

Upvotes: 0

Views: 690

Answers (1)

Daniel Hilgarth
Daniel Hilgarth

Reputation: 174467

The problem is that WithValue returns a DictionaryBuilder<T>, but the IndexRoute property returns the more specific type RouteValues. Try changing your property to return the DictionaryBuilder<T>:

public static DictionaryBuilder<RouteValueDictionary> IndexRoute 
{ 
    get 
    { 
        return new RouteValues()
            .WithValue("controller", "Admin")
            .WithValue("action", "Index"); 
    } 
}

An alternative to this would be to create a generic extension method to the DictionaryBuilder<T> class that returns the same type as the one that was passed in:

public static T WithValue(this T builder, string key, object obj)
{
        builder.WithValue(key, obj);
        return builder;
}

Upvotes: 3

Related Questions