Maksim SD
Maksim SD

Reputation: 19

Collection of different types C#

I have two classes OnlineBoolTag and OnlineDoubleTag. I add these objects to a list and want to get the Value of different types. How to return Value property of double or bool?

public class OnlineDoubleTag : IOnlineTag
{
    public string Name { get; set; }
    public double Value { get; set; }
}

public class OnlineBoolTag : IOnlineTag
{
    public string Name { get; set; }
    public bool Value { get; set; }
}

Add objects to a list:

var onlinetags = new List<IOnlineTag>();
onlinetags.Add(new OnlineBoolTag { Name = "Bool1", Value = true });
onlinetags.Add(new OnlineDoubleTag { Name = "Float1", Value = 777.22 });

foreach (var tag in onlinetags)
{
    Console.WriteLine(tag.*****Value*****);
}

Upvotes: 0

Views: 195

Answers (2)

shree.pat18
shree.pat18

Reputation: 21757

Using dynamic will help here, as Guy's answer points out. We can simplify this even further though, by defining the property Value to be of type dynamic itself. This removes the need to implement the interface for GetValue method. Instead, we can do this:

public class OnlineTag 
  {
    public string Name {get;set;}
    public dynamic Value {get;set;}
  }

public class Program 
  {
    public static void Main(string[] args) 
    {
     var onlinetags = new List<OnlineTag>();
     onlinetags.Add(new OnlineTag { Name = "Bool1", Value = true });
     onlinetags.Add(new OnlineTag { Name = "Float1", Value = 7777.22 });

     foreach (var tag in onlinetags)
      {
        Console.WriteLine($"{tag.Value} {tag.Value.GetType()}");
        //prints the below
        //True System.Boolean
        //7777,22 System.Double
      }
    }
  }

The pitfall with this is that defining Value as dynamic allows you to reassign a value of totally different type later on in your code. For example, the below code will not throw any errors:

Console.WriteLine($"{onlinetags[0].Value} {onlinetags[0].Value is bool}"); //prints True True
onlinetags[0].Value = 123M;
Console.WriteLine($"{onlinetags[0].Value} {onlinetags[0].Value.GetType()}"); // prints 123 System.Decimal

Upvotes: 0

Guy
Guy

Reputation: 50809

You can use dynamic instead of object

interface IOnlineTag
{
    public dynamic GetValue();
}

public class OnlineDoubleTag : IOnlineTag
{
    public string Name { get; set; }
    public double Value { get; set; }
    
    public dynamic GetValue()
    {
        return this.Value;
    }
}

public class OnlineBoolTag : IOnlineTag
{
    public string Name { get; set; }
    public bool Value { get; set; }
    
    public dynamic GetValue()
    {
        return this.Value;
    }
}

public static void Main()
{
    var onlinetags = new List<IOnlineTag>();
    onlinetags.Add(new OnlineBoolTag { Name = "Bool1", Value = true });
    onlinetags.Add(new OnlineDoubleTag { Name = "Float1", Value = 7777.22 });

    foreach (var tag in onlinetags)
    {
        Console.WriteLine($"{tag.GetValue()} {tag.GetValue().GetType()}");
    }
    
    // Value: True Type: System.Boolean
    // Value: 7777.22 Type: System.Double
}

Upvotes: 3

Related Questions