对泛型类中的类型进行特殊处理

时间:2009-07-14 18:45:14

标签: c# generics casting

对一般类中的类型进行特殊处理Pinnew member dan neely 19mins前

我正在尝试将一些旧的(最初的.net 1.1)抽象类汇总到泛型中。所讨论的类都为特定类型的数据对象提供类似的功能。事情进展顺利,但我遇到过一些地方,其中一个数据对象是一种类型,需要在一种方法中进行额外的处理,而不是所有其他类型所需的方法。我可以检查T的类型,看看它是否是我需要进行特殊处理的类型,但从T到SpecialType的转换将无法编译。有没有不同的方法可以做到这一点,或者我想做什么不可能?

class MyGenericClass : ICloneable where T: class, new()
{

private T  m_storedClass;
...

private DoStuff()
{
   //do stuff for all types

   //objects of SpecialType need extra stuff done.
   if (typeof(T) == typeof(SpecialType))
   {
      //compiler error:  Error Cannot convert type 'T' to 'SpecialType'
      ((SpecialType)m_storedClass).SpecialString = "foo";
   }
}

5 个答案:

答案 0 :(得分:3)

以下编译正常。

if (typeof(T) == typeof(SpecialClass))
{
    (this.m_storedClass as SpecialClass).SpecialOperation();
}

首先投射到Object是另一种解决方案。

if (typeof(T) == typeof(SpecialClass))
{
    ((SpecialClass)((Object)this.m_storedClass)).SpecialOperation();
}

请注意,支票也可以改写为以下内容。

if (this.m_storedClass is SpecialClass)
{
    (this.m_storedClass as SpecialClass).SpecialOperation();
}

或者只使用一个as运算符,包括免费检查条件中的非空值。

SpecialClass special = this.m_storedClass as SpecialClass;
if (special != null)
{
    special.SpecialOperation();
}

答案 1 :(得分:2)

这样的事情怎么样:

interface ISomething
{
    void DoSomething();
}

class NormalType : ISomething
{
    // ...
    public void DoSomething() { /* nothing to do */ }
}

class SpecialType : ISomething
{
    // ...
    public void DoSomething() { this.SpecialString = "foo" }
}

class MyGenericClass : ICloneable
{
    private ISomething m_storedClass;

    private DoStuff()
    {
        // ...
        m_storedClass.DoSomething();
    }
}

答案 2 :(得分:0)

除非你这样做,否则这将不起作用

class MyGenericClass : ICloneable 
    where T: class, new(), SpecialType

或者

class MyGenericClass : ICloneable 
    where T: class, new(), BaseTypeOfSpecialType

或者这个:

class MyGenericClass : ICloneable 
    where T: class, new(), InterfaceOnSpecialType

也许你不需要这样做 - 如果你发布一个更完整的问题,也许我可以帮你找出一种方法来避免不必这样做。

答案 3 :(得分:0)

你可以通过使用约束来使它工作,但这段代码有一个有趣的味道。

还有另一种方法可以在不破坏班级“通用性”的情况下在那里获得额外的处理吗?

答案 4 :(得分:0)

它在C#中不起作用,编译器不允许你这样做...如果你不能忍受别人建议的接口/基类限制,我有一个不太好但是工作解决方案:

您尝试执行的演员在C ++ / CLI中工作。你必须自己决定它是否值得。