【问题标题】:Generic method that can return different types可以返回不同类型的通用方法
【发布时间】:2014-08-08 19:43:00
【问题描述】:

我有一个基础抽象类,它允许实现者返回不同的类型:

protected abstract T GetMyValue<T>();

我希望实现类能够执行以下操作:

T myResult;    
public override T GetMyValue<T>()
{

     return _myResult;
}

我希望调用者指定类型:

int i = obj.GetMyValue<int>();

这可能吗?

【问题讨论】:

  • 是的...但是您需要为 T 提供合适的转换。您目前没有任何限制,如果我打电话给 GetMyValue&lt;Flob&gt; 会怎样?
  • 对可以返回的类型有什么限制吗?当你可以说int i = 5 时,这似乎有点矫枉过正。你会在编译时或运行时知道返回类型吗?
  • 每个继承基类的类都有自己的一组约束
  • 您是否希望具有GetMyValue 方法的给定类型能够返回任何类型,或者您是否希望类型A.GetMyValue 只能返回某些类型和类型@ 987654328@ 只能返回其他不同的类型?
  • 这些方法可以返回任何类型,也可以在每个实现者将其限制为 2-4 种类型的情况下对其进行约束(对于这种情况来说,这没什么大不了的)。我知道如果我将 GetMyValue 更改为返回 Object,它会给我我想要的东西,但我试图使用泛型来代替主要是为了性能而不是类型检查。

标签: c# .net generics


【解决方案1】:

像一个对象扩展?

public static class ObjectExtension
{
    public static T GetValue<T>(this object obj)
    {
        var converter = TypeDescriptor.GetConverter(typeof(T));

        if (converter == null)
            return default(T);

        return (T)converter.ConvertFrom(obj);
    }
}

【讨论】:

  • 如果你想要一个类上的方法,可能不是你想要的。
  • 这个答案恰好和我写的完整扩展方法超级接近。
【解决方案2】:

一种选择是将字段存储为对象。这会导致结构体装箱,但如果没有更显着的变化,就没有更好的方法了。

class Derived : Base
{
     private object o;

     protected override T GetMyValue<T>()
     {
        if (o is T)
           return (T)o;

        return default(T);
     }
}

除非抽象类本身是通用的,而不是特定的方法,否则你不能真正拥有通用字段。当然,这是一个重大的设计变化。一种实现现在只能返回一种类型。类似的东西

abstract class BaseClass<T>
{
    protected abstract T GetMyValue();
}

class Derived : Base<int>
{
    private int i;

    protected override int GetMyValue()
    {
        return i;
    }
}

【讨论】:

  • 让方法返回 Object 不是更好吗,这样每个类都不必担心转换,而只需调用者适当地转换。
  • @cppNoob 这完全取决于你想把这项工作交给谁。有人要投。问题是Derived 的实现者或调用者应该更容易吗?
【解决方案3】:

您必须以某种方式使该字段具有您想要返回的相同类型。这是一个技巧:

public override T GetMyValue<T>()
{
     return ValueHolder<T>.GetMyValue();
}

class ValueHolder<T> {
 static T myResult;    
 public static T GetMyValue()
 {
     return myResult;
 }
}

因为这是一个静态类,所以只能有一个这样的值。

如果您希望在您的实例中为每种类型设置一个值,您需要Dictionary&lt;Type, object&gt;

【讨论】:

    猜你喜欢
    • 2015-11-15
    • 1970-01-01
    • 1970-01-01
    • 2013-10-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多