代码之家  ›  专栏  ›  技术社区  ›  Kjara

为所有可浇铸类型定义通用浇铸

  •  0
  • Kjara  · 技术社区  · 5 年前

    public class InclusionData<T>
    {
        public T ThisObject { get; private set; }
        public T CopiedFromObject { get; private set; }
        public object OverwrittenOriginal { get; private set; }
    
        internal InclusionData(T thisObj, T copiedFromObj, object ovrwrtnOrgnl)
        {
            ThisObject = thisObj;
            CopiedFromObject = copiedFromObj;
            OverwrittenOriginal = ovrwrtnOrgnl;
        }
    }
    

    InclusionData<S> 为了什么 T S . 我该怎么做?

    (*不需要是显式/隐式强制转换,只需要以某种方式将 InclusionData<T> 然后走出一个 内容相同。)

    我试图在里面定义一种铸造方法 InclusionData 这样地:

    public InclusionData<S> Cast<S>() where T : S
    {
        return new InclusionData<S>((S)ThisObject, (S)CopiedFromObject, OverwrittenOriginal);
    }
    

    • T 在里面 where T : S 标记为红色,表示 'InclusionData<T>.Cast<S>()' does not define type parameter 'T'
    • (S)ThisObject 另外两个石膏都标上了红色,上面写着 cannot convert type 'T' to 'S'

    看来,虽然 T 使用 T . 那么我该如何具体说明呢 必须是可浇铸的 T

    0 回复  |  直到 5 年前
        1
  •  0
  •   Arcord    5 年前

    这是不可能的:

    public InclusionData<S> Cast<S>() where T : S
    

    因为T是具有约束的类型,但T未在方法级别定义。它是在类级别定义的。

    public InclusionData<S> Cast<S>() where S : T
    

    S(在方法级别定义的类型)将具有约束,该约束是T(在类级别定义的)的子级。

    之后,所有其他编译错误都消失了,但我不知道这是否就是您想要实现的?

        2
  •  0
  •   Sweeper    5 年前

    正如另一个答案所说, T : S 不是该方法可能的泛型约束,因为它是约束 T S .

    我将为此创建两个静态方法。通过这种方式,调用方可以指定要在其中转换的类型,并通过这样做,选择正确的方法:

    // "casting" from superclass to subclass
    public static InclusionData<S> Copy<S>(InclusionData<T> other) where S : T {
        return new InclusionData<S>((S)other.ThisObject, (S)other.CopiedFromObject, other.OverwrittenOriginal);
    }
    
    // "casting" from subclass to superclass
    public static InclusionData<T> Copy<S>(InclusionData<S> other) where S : T {
        return new InclusionData<T>(other.ThisObject, other.CopiedFromObject, other.OverwrittenOriginal);
    }
    

    用法示例:

    var d1 = new InclusionData<object>("Hello", "World", "Something");
    // I can convert from object to string...
    InclusionData<string> d2 = InclusionData<object>.Copy<string>(d1);
    // and from string to object
    d1 = InclusionData<object>.Copy<string>(d2);
    

    请注意,这不会处理值类型之间的内置转换,例如 int long