将 generic<T> 隐式转换回 T

Posted

技术标签:

【中文标题】将 generic<T> 隐式转换回 T【英文标题】:implicitly casting a generic<T> back to T 【发布时间】:2011-01-01 21:02:24 【问题描述】:

如果我编写一个像 MyGeneric&lt;T&gt; 这样的泛型类,是否可以编写一个隐式转换为 T 类型,所以我可以执行以下操作:

public class MyGeneric<T>

...


public class GenericProperties

   public MyGeneric<string> MyGenericString get;set;

   public void UseMyGeneric()
   
       string sTest = MyGenericString;
       MyGenericString = "this is a test";
   

是否可以通过重载运算符来做到这一点?我知道如果我的课程不是通用的,它可以做到......

【问题讨论】:

【参考方案1】:

是的..但不要过度,这往往会使人们感到困惑。我只会将它用于包装类型。

class Wrapper<T>

    public T Value get; private set;
    public Wrapper(T val) Value = val;

    public static implicit operator T(Wrapper<T> wrapper) return wrapper.Value;
    public static implicit operator Wrapper<T>(T val) return new Wrapper<T>(val);




var intWrapper = new Wrapper<int>(7);
var usingIt = 7 * intWrapper; //49

Wrapper<int> someWrapper = 9; //woohoo

【讨论】:

我支持你,因为它在技术上是正确的(最好的正确),但实际上,我认为这样做几乎不合适。我希望 OP 意识到这一点。 谢谢。我也为你投了赞成票,为了僵尸耶稣,因为我同意。 我很想看到这个的实际用途。 @nobugz: Nullable&lt;T&gt; 有一个explicit operator T。还有一个隐式转换来自 T。这很实用!【参考方案2】:

嗯,是的,但看在僵尸耶稣的份上,不要那样做。这真的很混乱。我认为您对泛型的目的略有误解。它不用于将类“转换”为该类型,它用于让该类型(MyGenericString)“了解”您想要的类型,用于各种目的(通常是基于集合的目的)。

【讨论】:

我同意,这个特性很有用,但是给出的例子看起来很糟糕,并且表明可能误解了泛型的目的。【参考方案3】:

正如其他人所说,这是合法危险。您可能会陷入许多陷阱。例如,假设您在C&lt;T&gt; 和 T 之间定义了一个用户定义的转换运算符。那么您说

C<object> c = new C<object>("hello");
object o = (object) c;

会发生什么?您的用户定义的转换是否运行? 不,因为 c 已经是一个对象。

就像我说的,当您尝试定义通用转换运算符时,您可能会遇到疯狂的情况; 除非您对规范的第 10.10.3 节有深入而详细的了解,否则不要这样做。

【讨论】:

【参考方案4】:

是的,可以使用隐式Conversion Operator Overloading

class Program

    static void Main(string[] args)
    
        myclass<string> a = new myclass<string>();
        a.inner = "Hello";
        string b = a;
        Console.WriteLine(b);
    


class myclass<T>

    public T inner;
    public myclass()
    

    
    public static implicit operator T(myclass<T> arg1)
    
        return arg1.inner;
    

【讨论】:

以上是关于将 generic<T> 隐式转换回 T的主要内容,如果未能解决你的问题,请参考以下文章

无法将类型“System.Collections.Generic.List<model1>”隐式转换为“System.Collections.Generic.List<model2&

无法将类型“System.Collections.Generic.List<xx.Test>”隐式转换为“xx.Test[]”

无法从 Task<> 隐式转换类型

无法将类型“IEnumerable<T>”隐式转换为“ActionResult<IEnumerable<T>>”

将(隐式)提升 shared_ptr<T> 转换为 shared_ptr<const T>

无法从“System.Collections.IList”转换为“System.Collections.Generic.IEnumerable<T>”