简体   繁体   中英

Indexer explicit implemented IFormattable

I wrote myself an indexer, it works but as soon as I implement "IFormatable" explicit, it does not work anymore.

Why is does it not work and how to use it explicit ?

This is what I tried:

/// <summary>
/// Example of Coordinates for 3 dimensions.
/// </summary>
public class Coordinates:IFormattable
{
    #region Constructor
    public Coordinates(int x, int y, int z)
    {
        _x = x;
        _y = y;
        _z = z;
        _length = 3;
    }
    #endregion
    #region IFormattable implemented
    /// <summary>
    /// Formating custom string
    /// </summary>
    /// <param name="format">Format("A"-all value,...,"H"-)</param>
    /// <param name="formatProvider">Different culture</param>
    /// <returns></returns>
    public string IFormattable.ToString(string format, IFormatProvider formatProvider)
    {
        if (format==null)
        {
            return ToString(); //Fallbasck
        }
        else
        {
            switch (format.ToUpper())//gross, kleinschreibung egal
            {
                case "A": return ToString();
                case "X": return _x.ToString();
                case "Y": return _y.ToString();
                case "Z": return _z.ToString();
                case "H": return String.Format("{0:h}", ToString());
                default:
                    throw new FormatException(String.Format("Format {0} is not defined.", format));
            }
        }
    }

    public string ToString(string format)
    {
        return ToString(format, null); //Error occurs here
    }

    #endregion
    #region overWriteToString
    /// <summary>
    /// will be called implicit
    /// </summary>
    /// <returns>[x,y,z]</returns>
    public override string ToString()
    {
        return String.Format("[{0},{1},{2}]",_x,_y,_z);
    }
    #endregion
    #region Properties
    private int _x;

    public int X
    {
        get { return _x; }
        set { _x = value; }
    }

    private int _y;

    public int Y
    {
        get { return _y; }
        set { _y = value; }
    }

    private int _z;

    public int Z
    {
        get { return _z; }
        set { _z = value; }
    }

    private int _length;

    public int Length
    {
        get { return _length; }
    }

    #endregion
    #region Indexer
    /// <summary>
    /// My own indexer for x,y,z
    /// </summary>
    /// <param name="val"></param>
    /// <returns></returns>
    public int this[int val]
    {
        get
        {

            switch (val)
            {
                case 0: return _x; ;
                case 1: return _y; ;
                case 2: return _z; ;
                default:
                    throw new IndexOutOfRangeException("Indexer not avaiable.");
            }

        }
        //kann auch setter haben
    }

    #endregion

}

I am learning C# in detail.

The error occurs here:

public string ToString(string format)
{
    return ToString(format, null); //Error occurs here
}

By implementing ToString(string format, IFormatProvider formatProvider) explicitly, you can only call it via a reference with a compile-time type of IFormattable .

You can do that by using this :

return ((IFormattable)this).ToString(format, null);

Or:

IFormattable formattable = this;
return formattable.ToString(format, null);

I'd probably add a comment to the code explaining why you're casting though, as it's not obvious until you notice that the method implements IFormattable.ToString explicitly.

Is there any reason you want to implement it explicitly, btw? It feels like something which should be accessible - and you should use the IFormatProvider passed in.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM