0

I'm trying to convert List<ICommonKline> to List<Candle> by using user-defined conversion, which doesn't let me do it because ICommonKline is an interface.

user-defined conversions to or from an interface are not allowed

How can I do that?

This is what I'm trying to accomplish:

List<ICommonKline> smt = (await api.GetCandlesAsync("TRXUSDT", TimeSpan.FromHours(1), limit: 500)).SkipLast(1).ToList();
List<Candle> smt2 = smt.Cast<Candle>().ToList(); // System.InvalidCastException: 'Unable to cast object of type 'Binance.Net.Objects.Spot.MarketData.BinanceSpotKline' to type 'NewBot.Core.Indicators.Candle'.'

Code:

public interface ICommonKline
{
    decimal CommonHigh { get; }
    decimal CommonLow { get; }
    decimal CommonOpen { get; }
    decimal CommonClose { get; }
}

public class Candle
{
    public decimal High { get; set; }
    public decimal Low { get; set; }
    public decimal Open { get; set; }
    public decimal Close { get; set; }
    public decimal Volume { get; set; }
    public DateTime OpenTime { get; set; }
    public DateTime CloseTime { get; set; }

    public static explicit operator Candle(ICommonKline candle) // error CS0552: 'Candle.explicit operator Candle(ICommonKline)': user-defined conversions to or from an interface are not allowed
    {
        var c = new Candle();



        return c;
    }
}
nop
  • 4,711
  • 6
  • 32
  • 93
  • 1
    Sorry my solution doesn't work, see (https://stackoverflow.com/questions/2433204/why-cant-i-use-interface-with-explicit-operator). But you could transfer the code from `explicit` to `Select()` lambda – Charlieface Jan 10 '21 at 21:39
  • You are trying to convert ICommonKline to Candle, not cast it, because Candle is not an ICommonKline, so don’t use cast nor the explicit operator. Just write a converter or an ConvertTo method. – Selmir Aljic Jan 10 '21 at 23:49

2 Answers2

0

Seems like that's the only good way.

var candles = new List<ICommonKline>();

...

return candles.Select(x => new Candle
{
    High = x.CommonHigh,
    Low = x.CommonLow,
    Open = x.CommonOpen,
    Close = x.CommonClose
}).ToList();
nop
  • 4,711
  • 6
  • 32
  • 93
0

Use constructor instead of operator

public class Candle
{
    public decimal High { get; set; }
    public decimal Low { get; set; }
    public decimal Open { get; set; }
    public decimal Close { get; set; }
    public decimal Volume { get; set; }
    public DateTime OpenTime { get; set; }
    public DateTime CloseTime { get; set; }

    public Candle(ICommonKline candle)
    {
         var c = new Candle();
         // ...
    }

    public Candle()
    {
    }
}

and then you could do conversion

List<Candle> smt2 = smt.Select(item => new Candle(item)).ToList();
Lucek
  • 111
  • 4