在泛型 class 中实现泛型接口方法
Implement generic interface method in generic class
有没有什么方法可以实现 interface ISetter
这样我在赋值时就不需要装箱了?直接转换 (T)value
显然是不可能的(编译器错误)。类型 T
可以是值或 class 类型。 interface ISetter
本身不能是通用的,因为它应该用作不同类型 T
.
的通用字典中的值类型
public interface ISetter
{
void Set<T>(T value);
}
public class Prop<T> : ISetter
{
public T Value;
//will be called always matching T1 == T
public void Set<T1>(T1 value)
{
if (typeof(T1) != typeof(T)) throw new ArgumentException();
Value = (T)(object)value; //is there any way to avoid boxing
}
}
据我所知,它实际上不应该将传递的值装箱。每个 T
和 T1
的组合都应该单独编译,这样编译器就可以优化部分代码,从而删除对 object
的“中间”转换。
下一个基准测试(使用 BenchmarkDotNet
)显示我的机器上没有分配(TargetFramework - netcoreapp3.1 安装了最新的 SDK):
[SimpleJob(RunStrategy.Monitoring)]
[MemoryDiagnoser]
public class BenchBoxedNonBoxedGeneric
{
private static Prop<int> GenericProp = new();
private static Prop NonGenericProp = new();
private const int Iterations = 1000_000_000;
[Benchmark]
public int NonGeneric()
{
for (int i = 0; i < Iterations; i++)
{
NonGenericProp.Set(i);
}
return NonGenericProp.Value;
}
[Benchmark]
public int Generic()
{
for (int i = 0; i < Iterations; i++)
{
GenericProp.Set(i);
}
return GenericProp.Value;
}
}
public class Prop<T>
{
public T Value;
public void Set<T1>(T1 value)
{
Value = (T)(object)value;
}
}
public class Prop
{
public int Value;
public void Set(int value)
{
Value = value;
}
}
Method
Mean
Error
StdDev
Allocated
NonGeneric
405.2 ms
26.76 ms
17.70 ms
-
Generic
383.2 ms
21.37 ms
14.14 ms
-
decompilation to JIT Asm with sharplab.io似乎也证明了这一点。
有没有什么方法可以实现 interface ISetter
这样我在赋值时就不需要装箱了?直接转换 (T)value
显然是不可能的(编译器错误)。类型 T
可以是值或 class 类型。 interface ISetter
本身不能是通用的,因为它应该用作不同类型 T
.
public interface ISetter
{
void Set<T>(T value);
}
public class Prop<T> : ISetter
{
public T Value;
//will be called always matching T1 == T
public void Set<T1>(T1 value)
{
if (typeof(T1) != typeof(T)) throw new ArgumentException();
Value = (T)(object)value; //is there any way to avoid boxing
}
}
据我所知,它实际上不应该将传递的值装箱。每个 T
和 T1
的组合都应该单独编译,这样编译器就可以优化部分代码,从而删除对 object
的“中间”转换。
下一个基准测试(使用 BenchmarkDotNet
)显示我的机器上没有分配(TargetFramework - netcoreapp3.1 安装了最新的 SDK):
[SimpleJob(RunStrategy.Monitoring)]
[MemoryDiagnoser]
public class BenchBoxedNonBoxedGeneric
{
private static Prop<int> GenericProp = new();
private static Prop NonGenericProp = new();
private const int Iterations = 1000_000_000;
[Benchmark]
public int NonGeneric()
{
for (int i = 0; i < Iterations; i++)
{
NonGenericProp.Set(i);
}
return NonGenericProp.Value;
}
[Benchmark]
public int Generic()
{
for (int i = 0; i < Iterations; i++)
{
GenericProp.Set(i);
}
return GenericProp.Value;
}
}
public class Prop<T>
{
public T Value;
public void Set<T1>(T1 value)
{
Value = (T)(object)value;
}
}
public class Prop
{
public int Value;
public void Set(int value)
{
Value = value;
}
}
Method | Mean | Error | StdDev | Allocated |
---|---|---|---|---|
NonGeneric | 405.2 ms | 26.76 ms | 17.70 ms | - |
Generic | 383.2 ms | 21.37 ms | 14.14 ms | - |
decompilation to JIT Asm with sharplab.io似乎也证明了这一点。