gpt4 book ai didi

c# - C# 中的条件泛型类型构造函数?

转载 作者:太空狗 更新时间:2023-10-29 23:56:33 26 4
gpt4 key购买 nike

假设你有一个泛型类 Foo :

public class Foo<T> {

public T Data {
get;
protected set;
}

}

是否可以定义一个仅适用于 T 的构造函数?继承(或是)特定类型。

例如说T是一个 int :

    public Foo () {
this.Data = 42;
}

应该在编译时 检查类型约束。这可能对优化有用。比如说你有一个 IEnumerable<T>并且您希望创建一个“缓存”(因为 LINQ 查询可能非常昂贵)。现在如果IEnumerable<T>已经是 IList<T> , 不复制数据是有用的。另一方面,如果它真的是一个 LINQ 查询,另一个构造函数可以将数据存储在一个数组中。


作为变通方法,当然可以继承Foo (例如 IntFoo )并在那里定义一个构造函数:

public class IntFoo : Foo<int> {

public IntFoo () {
this.Data = 42;
}

}

然而,这种方法的一个问题是 private数据不可访问(或者必须使其成为 protected )。是否还有其他一些缺点,或者是否应该以这种方式为特定类型的构造函数建模?

最佳答案

您可以在此处应用一个技巧。它适用于许多场景。

internal static class FooHelper
{
private static class DefaultData<T>
{
public static T Value = default(T);
}

static FooHelper()
{
DefaultData<int>.Value = 42;
DefaultData<string>.Value = "Hello World";
}

// From @JeffreyZhao:
//
// Use a static method to trigger the static constructor automatically,
// or we need to use RuntimeHelpers.RunClassConstructor to make sure
// DefaultData is corrected initialized.
//
// The usage of RuntimeHelpers.RunClassConstructor is kept but commented.
// Using GetDefault<T>() is a better approach since static Foo() would be
// called multiple times for different generic arguments (although there's
// no side affect in this case).
//
// Thanks to @mikez for the suggestion.
public static T GetDefault<T>()
{
return DefaultData<T>.Value;
}
}

public class Foo<T>
{
/* See the comments above.
static Foo()
{
RuntimeHelpers.RunClassConstructor(typeof(FooHelper).TypeHandle);
}
*/

public T Data { get; protected set }

public Foo()
{
Data = FooHelper.GetDefault<T>();
}
}

您可以为有限的类型指定默认值,并且它们的结果将保持默认值。

这个技巧在实践中有多种变化。在我的项目中,我们使用通用的 ITypeConverter<T>而不是内置 TypeConverter避免不必要的装箱:

public interface ITypeConverter<T>
{
bool CanConvertTo<TTarget>();
TTarget ConvertTo(T value);
}

可以应用相同的技巧:

public class LongConverter : ITypeConverter<long>
{
private static class Op<TTarget>
{
public static Func<long, TTarget> ConvertTo;
}

static LongConverter()
{
Op<string>.ConvertTo = v => v.ToString();
Op<DateTime>.ConvertTo = v => new DateTime(v);
Op<int>.ConvertTo = v => (int)v;
}

public TTarget ConvertTo<TTarget>(T value)
{
return Op<TTarget>.ConvertTo(value);
}
}

优雅、快速、干净。

关于c# - C# 中的条件泛型类型构造函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23924407/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com