C# 专门化泛型 class
C# specialize generic class
是否可以在 C# 中进行以下专业化?我可以在 C++ 中执行此操作,但不明白如何在 C# 中实现相同的结果。
class GenericPrinter<T>
{
public void Print()
{
Console.WriteLine("Unspecialized method");
}
}
class GenericPrinter<int>
{
public void Print()
{
Console.WriteLine("Specialized with int");
}
}
已添加:
建议的 GenericPrinterInt
解决方案的问题是我需要明确地创建它。 new GenericPrinter<int>
仍会打印 Unspecialized method
.
我想要的是使用来自另一个泛型 class 的这个 GenericPrinter 而没有知识是 T 等于 int 或其他东西。
我猜你在 C# 中越接近:
class GenericPrinter<T>
{
public virtual void Print()
{
Console.WriteLine("Unspecialized method");
}
}
class IntPrinter : GenericPrinter<int>
{
public override void Print()
{
Console.WriteLine("Specialized with int");
}
}
否则,答案是,你不能专攻C#。
正如 Lyubomyr Shaydariv 在他的评论中所说:
C++ templates are not .NET generics. You can't.
根据您的编辑,我猜您需要进行一些类型检查。
例如,您可以使用字典来做到这一点。
class GenericPrinter<T>
{
private Dictionary<Type, Action> _actions
= new Dictionary<Type, Action>()
{
{ typeof(int), PrintInt }
};
public virtual void Print()
{
foreach (var pair in _actions)
if (pair.First == typeof(T))
{
pair.Second();
return ;
}
Console.WriteLine("Unspecialized method");
}
public virtual void PrintInt()
{
Console.WriteLine("Specialized with int");
}
}
如您所见,您必须为每种类型创建一个方法,您要处理。当您尝试将 T 作为 int 进行操作时,您可能还会遇到一些问题。因为,T
是非常通用的(它没有任何约束),它更有可能在您的代码中充当 object
(而不是在运行时),您将不得不像那样转换它 (int)(object)yourTVariable
在你的方法 中你确定 T
是一个 int
.
但是对于这部分,我想我的一些同行会有比我更好的答案给你。
如果只是显示你正在使用的类型:
public virtual void Print()
{
Console.WriteLine($"Specialized with {typeof(T).Name}");
}
但是你不会再有非专业化的消息了(如果你考虑一下,你不能在没有指定类型的情况下实例化 GenericPrinter。那么有一个显示 [=47 的方法就没有意义了=], 你总会有一个指定的类型)
无论如何,答案还是一样,你不能在 C# 中专门化一个泛型。
在 C# 中不可能。
您可以改用继承:
class GenericPrinter<T>
{
public virtual void Print()
{
Console.WriteLine("Unspecialized method");
}
}
class GenericPrinterInt : GenericPrinter<int>
{
public override void Print()
{
Console.WriteLine("Specialized with int");
}
}
根据更新的问题,我只能建议你采用以下方法。您可以创建一个静态工厂方法,在该方法中您可以检查 T
的类型并在类型符合条件时实例化适当的专用 class:
class GenericPrinter<T>
{
public static GenericPrinter<T> Create()
{
if (typeof(int).IsAssignableFrom(typeof(T)))
return (GenericPrinter<T>)(object)new GenericPrinterInt();
if (typeof(double).IsAssignableFrom(typeof(T)))
return (GenericPrinter<T>)(object)new GenericPrinterDouble();
// Other types to check ...
return new GenericPrinter<T>();
}
public virtual void Print()
{
Console.WriteLine("Unspecialized method");
}
}
class GenericPrinterInt : GenericPrinter<int>
{
public override void Print()
{
Console.WriteLine("Specialized with int");
}
}
class GenericPrinterDouble : GenericPrinter<double>
{
public override void Print()
{
Console.WriteLine("Specialized with double");
}
}
其他一些通用的 class:
class SomeGenericClass<T>
{
public readonly GenericPrinter<T> Printer = GenericPrinter<T>.Create();
}
用法示例:
var intClass = new SomeGenericClass<int>();
intClass.Printer.Print();
// Output: Specialized with int
var doubleClass = new SomeGenericClass<double>();
doubleClass.Printer.Print();
// Output: Specialized with double
var stringClass = new SomeGenericClass<string>();
stringClass.Printer.Print();
// Output: Unspecialized method
是否可以在 C# 中进行以下专业化?我可以在 C++ 中执行此操作,但不明白如何在 C# 中实现相同的结果。
class GenericPrinter<T>
{
public void Print()
{
Console.WriteLine("Unspecialized method");
}
}
class GenericPrinter<int>
{
public void Print()
{
Console.WriteLine("Specialized with int");
}
}
已添加:
建议的 GenericPrinterInt
解决方案的问题是我需要明确地创建它。 new GenericPrinter<int>
仍会打印 Unspecialized method
.
我想要的是使用来自另一个泛型 class 的这个 GenericPrinter 而没有知识是 T 等于 int 或其他东西。
我猜你在 C# 中越接近:
class GenericPrinter<T>
{
public virtual void Print()
{
Console.WriteLine("Unspecialized method");
}
}
class IntPrinter : GenericPrinter<int>
{
public override void Print()
{
Console.WriteLine("Specialized with int");
}
}
否则,答案是,你不能专攻C#。
正如 Lyubomyr Shaydariv 在他的评论中所说:
C++ templates are not .NET generics. You can't.
根据您的编辑,我猜您需要进行一些类型检查。
例如,您可以使用字典来做到这一点。
class GenericPrinter<T>
{
private Dictionary<Type, Action> _actions
= new Dictionary<Type, Action>()
{
{ typeof(int), PrintInt }
};
public virtual void Print()
{
foreach (var pair in _actions)
if (pair.First == typeof(T))
{
pair.Second();
return ;
}
Console.WriteLine("Unspecialized method");
}
public virtual void PrintInt()
{
Console.WriteLine("Specialized with int");
}
}
如您所见,您必须为每种类型创建一个方法,您要处理。当您尝试将 T 作为 int 进行操作时,您可能还会遇到一些问题。因为,T
是非常通用的(它没有任何约束),它更有可能在您的代码中充当 object
(而不是在运行时),您将不得不像那样转换它 (int)(object)yourTVariable
在你的方法 中你确定 T
是一个 int
.
但是对于这部分,我想我的一些同行会有比我更好的答案给你。
如果只是显示你正在使用的类型:
public virtual void Print()
{
Console.WriteLine($"Specialized with {typeof(T).Name}");
}
但是你不会再有非专业化的消息了(如果你考虑一下,你不能在没有指定类型的情况下实例化 GenericPrinter。那么有一个显示 [=47 的方法就没有意义了=], 你总会有一个指定的类型)
无论如何,答案还是一样,你不能在 C# 中专门化一个泛型。
在 C# 中不可能。
您可以改用继承:
class GenericPrinter<T>
{
public virtual void Print()
{
Console.WriteLine("Unspecialized method");
}
}
class GenericPrinterInt : GenericPrinter<int>
{
public override void Print()
{
Console.WriteLine("Specialized with int");
}
}
根据更新的问题,我只能建议你采用以下方法。您可以创建一个静态工厂方法,在该方法中您可以检查 T
的类型并在类型符合条件时实例化适当的专用 class:
class GenericPrinter<T>
{
public static GenericPrinter<T> Create()
{
if (typeof(int).IsAssignableFrom(typeof(T)))
return (GenericPrinter<T>)(object)new GenericPrinterInt();
if (typeof(double).IsAssignableFrom(typeof(T)))
return (GenericPrinter<T>)(object)new GenericPrinterDouble();
// Other types to check ...
return new GenericPrinter<T>();
}
public virtual void Print()
{
Console.WriteLine("Unspecialized method");
}
}
class GenericPrinterInt : GenericPrinter<int>
{
public override void Print()
{
Console.WriteLine("Specialized with int");
}
}
class GenericPrinterDouble : GenericPrinter<double>
{
public override void Print()
{
Console.WriteLine("Specialized with double");
}
}
其他一些通用的 class:
class SomeGenericClass<T>
{
public readonly GenericPrinter<T> Printer = GenericPrinter<T>.Create();
}
用法示例:
var intClass = new SomeGenericClass<int>();
intClass.Printer.Print();
// Output: Specialized with int
var doubleClass = new SomeGenericClass<double>();
doubleClass.Printer.Print();
// Output: Specialized with double
var stringClass = new SomeGenericClass<string>();
stringClass.Printer.Print();
// Output: Unspecialized method