【问题标题】:C# Generic classes and casting with WCFC# 泛型类和使用 WCF 进行强制转换
【发布时间】:2009-05-29 08:54:37
【问题描述】:

我想编写一个泛型类,它应该使用不同的泛型参数强制转换为自身。

class Base {}
class Inherited : Base {}

class MyGeneric<T> {}

// WCF Service interface
void Foo(MyGeneric<Base> b);

// somewhere else
MyGeneric<Inherited> inherited;
Foo(inherited)

我知道这可以在 C# 4.0 中完成,但现在没有帮助。

  • 我可以为每个MyGeneric&lt;T&gt; 星座编写一个专门的类,并在那里编写一个隐式类型转换器或实现某个接口。但我想避免这种情况。
  • 我可以有一个没有泛型的接口,但在这种情况下,泛型的整体意义是在方法 Foo 上获得编译时类型安全。所以这不是一个选择。
  • 因为 Foo 是一个 Operation Contract,所以它本身不能是泛型的。

任何想法如何在 C# 3.0 中解决这个问题?

【问题讨论】:

    标签: c# wcf generics casting


    【解决方案1】:

    你想要:

    void Foo<T>(MyGeneric<T> b) where T : Base {}
    

    【讨论】:

    • 哦,是的,这在“内部”有效,我忘了说 Foo 也是一个 ServiceContract...
    • 你的意思是OperationContract吗?
    • 是的,我指的是 OperationContract
    • 那么我不确定它在WCF下是否“可行”,除了列表类型(有不同的处理方式)。
    • 尝试编写 Cast 方法。这有点安全,但也有点尴尬。请参阅我自己的答案。
    【解决方案2】:

    这个铸造方法是我写的

    public MyGeneric<TTarget> Cast<TTarget, TSource>()
      where TTarget : class
      where TSource : TTarget, T
    {
      return new MyGeneric<TTarget>();
    }
    

    可以这样调用

    MyGeneric<Inherited> inherited;
    Foo(inherited.Cast<Base, Inherited>());
    

    丑陋的事情是必须提供它已经存在的类。可能会有一些改进。

    顺便说一句,为了避免第二个泛型参数,我无法将其设为扩展方法。

    【讨论】:

      【解决方案3】:

      在这种情况下,泛型的整体意义是在方法 Foo 上获得编译时类型安全

      以这种方式强制转换的目的(对不在实例祖先中的类型)是为了破坏类型安全。不要破坏类型安全以保存类型安全。

      【讨论】:

      • 是的。我正是这个意思。我不能告诉 C# 只允许具有从接口中派生的泛型参数的类型。我不想在任何地方破坏类型安全。
      • 就好像 MyGeneric 是 MyGeneric 的父级一样工作会破坏类型安全。
      • 如果我有一个 Base 参数并传递一个 Inherited 实例,那就没问题了。这是正常的,类型安全的多态性。 MyGeneric 实际上是业务对象的包装器,您可以将其视为业务对象描述符。它替换了 Base 类型的参数。使用泛型类,我得到不兼容的类型。目标是恢复多态性。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-02-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多