Matthew Underwood
Matthew Underwood

Reputation: 1499

Cast instance in list to its generic interface

I have a list of instances BasicReference and TaggableReference, that implements a generic interface IReference

BasicReference.cs

namespace DefaultNamespace
{
    public class BasicReference : IReference<string>
    {
        public string Resolve(string name)
        {
            return name;
        }

        public bool Valid(string name)
        {
            return (name != null);
        }
    }
}

TaggableReference.cs

namespace DefaultNamespace
{
    public class TaggableReference : IReference<(string,string)>
    {
        public (string,string) Resolve(string name)
        {
            return (name + "1",name + "2");
        }

        public bool Valid(string name)
        {
            return (name != null);
        }
    }
}

IReference.cs

namespace DefaultNamespace
{
    public interface IReference<out T>
    {
        T Resolve(string name);
        bool Valid(string name);
    }
}

I can add BasicReference and TaggableReference to a list where Type parameter is object. But how do i cast them to call the methods from IReference? And what type do I return from the method?

using System.Collections.Generic;

namespace DefaultNamespace
{
    public class Test
    {
        private List<object> references = new List<object>();

        public ??? Test()
        {
            references.Add(new BasicReference());
            references.Add(new TaggableReference());

            string referenceExample = "example";

            foreach (var reference in references)
            {
                // How can I cast this so I can call IReference methods and return the type
                // What type do I return from method?
                if (reference.Valid(referenceExample))
                {
                    ??? result = reference.Resolve(referenceExample);    
                } 
            }
        }
    }
}

Upvotes: 0

Views: 36

Answers (1)

devNull
devNull

Reputation: 4219

As long as you know the type you're expecting when calling the Test() method, you can make that method generic as well and return the reference for the given type:

public T Test<T>()
{
    references.Add(new TaggableReference());
    references.Add(new BasicReference());

    string referenceExample = "example";

    foreach (var reference in references.OfType<IReference<T>>())
    {
        if (reference.Valid(referenceExample))
        {
            return reference.Resolve(referenceExample);
        }
    }

    return default; // Handle type not found accordingly
}

The usage of this would be:

var reference = test.Test<string>();
Console.WriteLine(reference);

var taggableReference = test.Test<(string, string)>();
Console.WriteLine(taggableReference);

Which produces the expected output:

enter image description here

Upvotes: 1

Related Questions