C# Converting object to int without casting

I have a method that returns a type of object based on the given column (a database class). However, when I assign the object the compiler throws an error saying it cannot implicitly convert type of object to int. How can I convert it without casting?

It looks better as:

this.Id = datum["Id"];

But now I have to include a cast, which makes the code a bit less clean and harder to code:

this.Id = (int)datum["Id"];

Here's my code:

public object this[string name]
    {
        get
        {
            object result;

            if (this.Dictionary.ContainsKey(name))
            {
                if (this.Dictionary[name] is DBNull)
                {
                    result = null;
                }
                else if (this.Dictionary[name] is byte && Meta.IsBool(this.Table, name))
                {
                    result = (byte)this.Dictionary[name] > 0;
                }
                else
                {
                    result = this.Dictionary[name];
                }
            }
            else
            {
                result = default(object);
            }

            return result;
        }
        set
        {
            if (value is DateTime)
            {
                if (Meta.IsDate(this.Table, name))
                {
                    value = ((DateTime)value).ToString("yyyy-MM-dd");
                }
                else if (Meta.IsDateTime(this.Table, name))
                {
                    value = ((DateTime)value).ToString("yyyy-MM-dd HH:mm:ss");
                }
            }

            if (this.Dictionary.ContainsKey(name))
            {
                this.Dictionary[name] = value;
            }
            else
            {
                this.Dictionary.Add(name, value);
            }
        }
    }
Jon Skeet
people
quotationmark

You could change your indexer signature to:

public dynamic this[string name]

That would then make the conversion dynamic at execution time.

Personally, I prefer the cast approach though. It makes it clear that this is something that can fail - that you're telling the compiler that you have information which isn't available to it.

As an aside, your code can be written rather more simply, taking advantage of Dictionary<,>.TryGetValue and the behaviour of the dictionary indexer for setting:

public object this[string name]
{
    get
    {
        object result;
        if (Dictionary.TryGetValue(name, out result))
        {
            if (result is DBNull)
            {
                result = null;
            }
            else if (result is byte && Meta.IsBool(this.Table, name))
            {
                result = (byte) result > 0;
            }
        }
        return result;
    }
    set
    {
        // TODO: Byte/bool conversions?

        if (value is DateTime)
        {
            // Note use of invariant culture here. You almost certainly
            // want this, given the format you're using. Preferably,
            // avoid the string conversions entirely, but...
            DateTime dateTime = (DateTime) value;
            if (Meta.IsDate(this.Table, name))
            {
                value = dateTime.ToString("yyyy-MM-dd", CultureInfo.InvariantCulture);
            }
            else if (Meta.IsDateTime(this.Table, name))
            {
                value = dateTime.ToString("yyyy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture);
            }
        }

        Dictionary[name] = value;
    }
}

people

See more on this question at Stackoverflow