C#泛型不承认类型不承认、类型

2023-09-04 02:45:01 作者:君臣

我不明白,为什么下面的code返回无法解析方法Write(T) - 它似乎毫不含糊的对我说:

 私有静态无效WriteToDisk< T>(字符串文件名,T []载体)
    {
        使用(VAR流=新的FileStream(文件名,FileMode.Create))
        {
            使用(VAR作家=新的BinaryWriter(流))
            {
               的foreach(T V IN载体)writer.Write(V);
                writer.Close();
            }
        }
    }
 

我想定义可以用,例如, INT [] 长[] 或双[]

解决方案

cdhowie有正确的解释。重载发生在编译​​时,在这种情况下没有人知道关于 T ,所以无过载都是适用的。

使用动态,重载发生运行时。也许你可以使用:

  writer.Write((动态)V)
 
关于C 的泛型方法

这将是因为拳击和反复重载解析发生运行时的速度有点慢。

编辑::如果由于某种原因你没有访问动态,你可以得到明确体现出类似的行为:

 私有静态无效WriteToDisk< T>(字符串文件名,T []载体)
{
    VAR correctMethod = typeof运算(的BinaryWriter).GetMethod(写,新的[] {typeof运算(T),});
    如果(correctMethod == NULL)
        抛出新的ArgumentException(没有合适的重载发现型+ typeof运算(T),T);
    使用(VAR流=新的FileStream(文件名,FileMode.Create))
    {
        使用(VAR作家=新的BinaryWriter(流))
        {
           的foreach(矢量VAR V)
               correctMethod.Invoke(作家,新的对象[] {V,});
        }
    }
}
 

我不知道这是不是动态

更快或更慢

在这两种情况下,如果你不小心使用类型 T (如的DateTime ),这是不支持的的BinaryWriter ,一切都将编译很好,你只会发现你的错误在运行时(在code运行时)。见jam40jeff的答案,你通过传递委托实例的方法指定自己的过载多种类型的安全解决方案。

I can't figure out why the following code returns a Cannot resolve method Write(T) - it seems unambiguous to me:

    private static void WriteToDisk<T>(string fileName, T[] vector)
    {
        using (var stream = new FileStream(fileName, FileMode.Create))
        {
            using (var writer = new BinaryWriter(stream))
            {
               foreach(T v in vector) writer.Write(v);
                writer.Close();
            }
        }
    }

I would like to define a generic binary write method that can deal with vectors of, e.g., int[], long[] or double[].

解决方案

cdhowie has the correct explanation. Overload resolution happens at compile-time, and in this case nothing is known about T, so no overload is applicable.

With dynamic, overload resolution happens runtime. Maybe you can use:

writer.Write((dynamic)v)

It will be a bit slow because of boxing and repeated overload resolution taking place runtime.

Edit: If for some reason you don't have access to dynamic, you can get a similar behavior with explicit reflection:

private static void WriteToDisk<T>(string fileName, T[] vector)
{
    var correctMethod = typeof(BinaryWriter).GetMethod("Write", new[] { typeof(T), });
    if (correctMethod == null)
        throw new ArgumentException("No suitable overload found for type " + typeof(T), "T");
    using (var stream = new FileStream(fileName, FileMode.Create))
    {
        using (var writer = new BinaryWriter(stream))
        {
           foreach(var v in vector)
               correctMethod.Invoke(writer, new object[] { v, });
        }
    }
}

I don't know if this is faster or slower than dynamic.

In either case, if you accidentally use a type T (such as DateTime) which is not supported by BinaryWriter, everything will compile fine, and you will only discover your mistake at runtime (when the code runs). See jam40jeff's answer for a more type-safe solution where you specify the overload yourself by passing in a delegate instance to the method.

 
精彩推荐
图片推荐