【问题标题】:Cast instance in list to its generic interface将列表中的实例转换为其通用接口
【发布时间】:2020-03-08 18:57:37
【问题描述】:

我有一个实例 BasicReference 和 TaggableReference 的列表,它们实现了一个通用接口 IReference

基本参考.c​​s

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);
    }
}

我可以将 BasicReference 和 TaggableReference 添加到类型参数为对象的列表中。但是我如何让它们从 IReference 调用方法呢?我从方法返回什么类型?

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);    
                } 
            }
        }
    }
}

【问题讨论】:

  • 您希望Test() 方法如何被调用?知道这可能有助于理解如何构建代码
  • 我希望 Test 返回从 Basic Reference 或 TaggableReference 返回的类型。基本上我需要能够说它是一个字符串或字符串的元组。
  • IReference&lt;(string,string)&gt;IReference&lt;string&gt; 完全不一样,所以需要先检查一下:if (obj is IReference&lt;string&gt; iRefStr) iRefStr.Valid("test");

标签: c# oop generics interface


【解决方案1】:

只要您知道调用Test() 方法时所期望的类型,您也可以将该方法设为泛型并返回给定类型的引用:

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
}

这个的用法是:

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

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

产生预期的输出:

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-15
    • 2011-01-01
    • 2021-12-25
    • 1970-01-01
    相关资源
    最近更新 更多