首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >是否可以将泛型类型的实例传递给其他强类型方法?

是否可以将泛型类型的实例传递给其他强类型方法?
EN

Stack Overflow用户
提问于 2009-03-13 22:29:03
回答 4查看 549关注 0票数 2

我有一种情况,我有一个需要几个重载的方法。我有一个相当常见的场景,如果某个条件为真,我会调用其中一个重载,否则我会调用其他重载。我决定聪明一点,把通用代码重构为一个泛型方法,该方法接受一个对象和一个条件,然后调用重载的方法或调用通用代码。

一个非常简单的代码示例:

代码语言:javascript
复制
/// <summary>
/// Dummy interface
/// </summary>
public interface ITest1
{ }
/// <summary>
/// Dummy interface
/// </summary>
public interface ITest2
{ }
/// <summary>
/// Generic Class
/// </summary>
public class GenericClass
{
    /// <summary>
    /// First overload
    /// </summary>
    /// <param name="test1"></param>
    public void TestMethod(ITest1 test1)
    { }
    /// <summary>
    /// Second overload
    /// </summary>
    /// <param name="test2"></param>
    public void TestMethod(ITest2 test2)
    { }

    /// <summary>
    /// method with common logic
    /// </summary>
    /// <typeparam name="TInterfaceType">
    /// Type of the test object
    /// </typeparam>
    /// <param name="test">
    /// Test object to pass to the method.
    /// </param>
    public void ConditionallyCallTest<TInterfaceType>(
          TInterfaceType test, bool someLogic)
    {
        if (someLogic)
        {
            this.TestMethod(test);
        }
        else
        {
            // .. Perform Common operations here
        }
    }
}

忽略这一事实,如果你编译这段代码,你会得到一个编译器错误,它不能将TInterfaceType转换成ITest1。

我希望编译器等到我指定要进行类型检查的类型,所以:

代码语言:javascript
复制
GenericClass g = new GenericClass();
// We have an overload, so this is OK:
g.ConditionallyCallTest<ITest1>(test1);
// We have an overload, so this is OK:
g.ConditionallyCallTest<ITest2>(test2);
// Compiler error, no overload available:
g.ConditionallyCallTest<UnknownType>(obj);

有没有可能用C#来做这样的事情?

我还尝试使用where子句指定允许的类型,但我不知道如何让where子句指定指定类型之间的一个或多个关系,只指定一个AND关系。

编辑

当我使用mentioned in the comments below时,我试图避免创建匹配的重载方法,那么有没有其他建议来解决这个问题,或者我是否受到了这里的语言的限制?

EN

回答 4

Stack Overflow用户

发布于 2009-03-13 22:46:07

你甚至需要一个泛型方法吗?只需使用普通重载即可。

代码语言:javascript
复制
/// <summary>
/// Dummy interface
/// </summary>
public interface ITest1
{ }
/// <summary>
/// Dummy interface
/// </summary>
public interface ITest2
{ }
/// <summary>
/// Generic Class
/// </summary>
public class GenericClass
{
    /// <summary>
    /// First overload
    /// </summary>
    /// <param name="test1"></param>
    public void TestMethod(ITest1 test1)
    { }
    /// <summary>
    /// Second overload
    /// </summary>
    /// <param name="test2"></param>
    public void TestMethod(ITest2 test2)
    { }

    public void ConditionallyCallTest(ITest1 test, bool someLogic)
    {
        if(Common(someLogic))
            return;

        TestMethod(test);
    }

    public void ConditionallyCallTest(ITest2 test, bool someLogic)
    {
        if(Common(someLogic))
            return;

        TestMethod(test);
    }

    private bool Common(bool someLogic)
    {
        if (someLogic)
        {
            return false;
        }

        // .. Perform Common operations here
        return true;
    }
}
票数 2
EN

Stack Overflow用户

发布于 2009-03-13 22:57:44

为所有类型抽象出一个公共接口,并为此使用多态性。

票数 2
EN

Stack Overflow用户

发布于 2009-03-13 22:35:50

编译器必须能够在不知道要传递什么的情况下编译代码。在本例中,我所说的“你的代码”指的是包含方法的类。

换句话说,它必须知道对TestMethod的调用是合法的,这是基于它在编译执行调用的方法时所知道的情况。

在这种情况下,它对TInterfaceType一无所知,因此不能保证这是正常的,因此它会抱怨。

您可以告诉编译器TInterfaceType泛型类型必须实现一个或多个接口,但不能告诉它该类型必须实现一个或另一个接口。

换句话说,不,你不能在没有一些造型的情况下做到这一点。

要做到这一点,一种方法是创建多个重载,每个重载对应于您希望支持的每种接口类型。

泛型类型基本上是为了“任何可能的类型”,其中你有一个有限的类型集是允许的。

使用泛型时,如果不显式检查类型是实现一个接口还是另一个接口(即强制转换),就无法做到这一点,从而直接调用显式方法。

您也不能重载该方法,并通过泛型约束来区分它,因为方法签名不能仅通过泛型约束来区分。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/644841

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档