4

我让自己陷入了 22 条陷阱,似乎找不到出路。我正在尝试实现一个简单的 [Service Locator][1],由下面示例代码中的 GetInstance 方法表示。现在的问题是我在 return 语句上得到一个编译器错误,说:

Cannot implicitly convert type 'Cyberspace.SubClass' to 'Cyberspace.BaseClass<T>'

我已经尝试重写,以便 SubClass 本身就是一个泛型类,但随后我在 DoSomething 方法中的 return 语句上得到编译器错误。

任何人都可以编译此代码,保留允许我在 GetInstace 方法中具有抽象返回类型的服务定位器模式原则吗?还是我想在这里实现一些不可能的事情?

namespace Cyberspace
{
    class BaseClass<T>
    {
        BaseClass<T> GetInstance() 
        { 
            return new SubClass();
        }
        virtual T DoSomething() { return default(T); }          
    }

    class SubClass : BaseClass<OtherClass>
    {
        public override OtherClass DoSomething()
        { 
            var other = new OtherClass { Description = "Generics are hard"};
            return other;
        }
    }

    class OtherClass
    {
        internal string Description { get; set; }
    }
}

尝试2:

namespace Cyberspace
{
    class BaseClass<T>
    {
        static BaseClass<T> GetInstance() // The "Service Locator" method
        { 
            return new SubClass<T>(); 
        }
        internal virtual T DoSomething() { return default(T); }        
    }

    class SubClass<T> : BaseClass<T> where T: OtherClass
    {
        internal override T DoSomething()
        { 
            var other = new OtherClass { Description = "Generics are hard"};
            return (T) other;
        }
    }

    class OtherClass
    {
        internal string Description { get; set; }
    }
}

这会在线产生以下错误return new SubClass<T>();

The type 'T' cannot be used as type parameter 'T' in the generic type or method 'Cyberspace.SubClass<T>'. There is no boxing conversion or type parameter conversion from 'T' to 'Cyberspace.OtherClass'

4

2 回答 2

3

我不清楚你真正想要做什么,但我可以告诉你为什么会发生编译错误。

从此方法返回的任何内容:

BaseClass<T> GetInstance()

必须能够处理任何类型T(因为您没有类型约束)。SubClass只能处理一种类型,而不是所有类型。因此,您无法退货。

于 2012-06-28T13:41:20.573 回答
1

使用类型参数T时,您声明:“我不在乎实际是什么类型。我只需要一些类型,任何类型。调用它T。”。但在您的情况下,您似乎想要一个特定的类型。那么就不需要泛型了。

class SubClass : BaseClass<OtherClass>
{
    internal override OtherClass DoSomething()
    { 
        var other = new OtherClass { Description = "Generics are hard"};
        return other;
    }
}

为什么以下不起作用?

        var other = new OtherClass { Description = "Generics are hard"};
        return (T) other;

因为T可能源自OtherClass. 您不能转换OtherClass为从OtherClass. 没有意义,编译器足够聪明,可以捕捉到它。


评论中的讨论导致以下解决方法:

return (BaseClass<T>)(object)new SubClass();

当然,这仅适用于类型在运行时对齐的情况。

于 2012-06-28T14:01:50.953 回答