【问题标题】:Casting a generic class which is an object to it's type将作为对象的泛型类转换为它的类型
【发布时间】:2014-04-10 15:57:48
【问题描述】:

这是一个与泛型相关的类层次问题。我有一个主要派生类MyClass3<T>,它派生自MyClass2<T>。 MyClass2<T> 类有一个名为 MyProperty 的属性。

我有一个方法 VerifyMyProperty,它接受 MyClass3 类型的对象。既然是泛型,就可以是MyClass3<A> or MyClass3<B> or MyClass3<C>。

我的问题是,如何将 MyClass3 转换为 MyClass2 以检查属性 MyProperty?如果没有泛型,就像var myClass2 = anyofMyClass as MyClass2 一样容易。对于 T 可以是 A、B 或 C 的泛型,我该如何进行相同的转换?

public class MyClass3<T> : MyClass2<T>
{
....
}

public class MyClass2<T> : MyClass1
{
    T MyProperty { get; private set; }
}

public void VerifyMyProperty(object anyofMyClass)
{
    var myClass2 = anyofMyClass as MyClass2; // Finding the MyClass2. This line will return a compiler error.

    if (myClass2.MyProperty != null)
    {
       Console.Writeline("MyClass2.MYProperty is not null.");
    }
}

【问题讨论】:

  • 我认为当它们本质上不同时,您不能将一种类型的对象转换为另一种类型;您可能必须创建一个单独的实例 - 尽管我的知识有限。
  • 你到底想做什么?为什么一个类要尝试验证完全不同的其他类型的属性?
  • 我以VerifyMyProperty方法为例进行介绍。目的是检查 MyProperty 的 null 状态并显示一条消息。 VerifyMyProperty 所在的类位于框架方法中,我没有太多控制权来更改它。

标签: c# oop generics


【解决方案1】:

首先:在您的示例中,MyClass2 不存在。只有MyClass&lt;T&gt; 是一个有效的类。

所以你可以考虑:

var myClass2 = anyofMyClass as MyClass2&lt;T&gt;;

如果anyOfMyClass 必须能够包含具有另一个泛型类型的 MyClass2,则会出现问题。

您可能需要考虑一个具有如下属性的通用接口的实现:

interface IMyInterface
{
    object MyProperty { get; }
}

public class MyClass2<T> : MyClass1, IMyInterface
{
    T MyProperty { get; private set; }
    object IMyInterface.MyProperty { get { return MyProperty; }}
}

当您显式实现此接口时(请参阅:http://msdn.microsoft.com/en-us/library/aa664591(v=vs.71).aspx),您可以通过非通用方式解决您的问题:

var myClass2 = anyofMyClass as IMyInterface;
if (myClass2.MyProperty != null)
    ...

【讨论】:

  • 感谢您的反馈。但是这两种解决方案都行不通。类型 T 需要在编译时提供。所以编译器会在这一行给出错误'var myClass2 = anyofMyClass as MyClass2;'第二种解决方案也不起作用,因为“MyClass2”将强制“MyProperty”为“object”类型。
  • 如果我从 IMyInterface 派生 MyClass2,MyProperty 应该是对象类型。我相信这就是您所说的显式实现的意思。我不想这样做,因为 MyClass3 的其他消费者想要处理真实类型本身,而不是对象。
  • 不,您指的是隐式实现。此处解释了显式实现:msdn.microsoft.com/en-us/library/aa664591(v=vs.71).aspx。我还更新了代码以便更好地理解。
  • 谢谢先生。这有效并且是一个答案。但是在查看您的答案后,我现在正在寻找不同的解决方案。我可以引入一个名为“I”的新接口,并且所有类型 A、B、C 都从该接口 I 派生。然后我可以使用“var myClass2 = anyofMyClass as MyClass2”。我不知道 contra 变体是否是这个问题的 NEAT 解决方案。
  • 也许你应该对所有新代码提出一个新问题。界面中有什么?你还想读那个属性吗?
猜你喜欢
  • 1970-01-01
  • 2013-05-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-01-01
  • 1970-01-01
相关资源
最近更新 更多