C# 以类型泛型/不可知的方式实现泛型方法的最佳方法
假设我们有一个具有此类签名的通用方法:C# 以类型泛型/不可知的方式实现泛型方法的最佳方法,c#,generics,factory-method,C#,Generics,Factory Method,假设我们有一个具有此类签名的通用方法: T Obfuscate<T>(T value) where T : IConvertible 这肯定有工厂方法的味道,必须调用特定的实现提供程序,但仍然需要进行类型检查 对于这种情况,您认为哪种方法最好(希望是通用方法? 为什么是泛型方法? 我决定使用泛型方法,这样它总是返回正确的类型,而不需要在调用代码中强制转换方法返回。正如您所说,您必须执行一些描述的类型检查。但是,您可以轻松地将其分解为更小的方法,甚至可以使用开放注册方案: priva
T Obfuscate<T>(T value) where T : IConvertible
这肯定有工厂方法的味道,必须调用特定的实现提供程序,但仍然需要进行类型检查
对于这种情况,您认为哪种方法最好(希望是通用方法?
为什么是泛型方法?
我决定使用泛型方法,这样它总是返回正确的类型,而不需要在调用代码中强制转换方法返回。正如您所说,您必须执行一些描述的类型检查。但是,您可以轻松地将其分解为更小的方法,甚至可以使用开放注册方案:
private readonly Dictionary<Type, Delegate> obfuscators =
new Dictionary<Type, Delegate>;
// Alternatively, register appropriate obfuscators on construction.
public void RegisterConverter<T>(Func<T, T> obfuscator)
{
obfuscators[typeof(T)] = obfuscator;
}
public T Obfuscate<T>(T value)
{
Delegate obfuscator;
if (obfuscators.TryGetValue(typeof(T), out obfuscator)
{
// We know it'll be the right type...
var realObfuscator = (Func<T, T>) obfuscator;
return realObfuscator(value);
}
// ??? Throw exception? Return the original value?
}
专用只读字典混淆器=
新词典;
//或者,在构建时注册适当的模糊器。
公共无效注册表转换器(Func模糊器)
{
模糊器[类型(T)]=模糊器;
}
公共T混淆(T值)
{
委托模糊器;
if(模糊器.TryGetValue(类型(T),输出模糊器)
{
//我们知道这将是正确的类型。。。
var realObfuscator=(Func)模糊算子;
返回realObfuscator(值);
}
//?抛出异常?返回原始值?
}
正如您所说,您必须执行一些描述的类型检查。但是,您可以很容易地将其分解为较小的方法,甚至有一个开放的注册方案:
private readonly Dictionary<Type, Delegate> obfuscators =
new Dictionary<Type, Delegate>;
// Alternatively, register appropriate obfuscators on construction.
public void RegisterConverter<T>(Func<T, T> obfuscator)
{
obfuscators[typeof(T)] = obfuscator;
}
public T Obfuscate<T>(T value)
{
Delegate obfuscator;
if (obfuscators.TryGetValue(typeof(T), out obfuscator)
{
// We know it'll be the right type...
var realObfuscator = (Func<T, T>) obfuscator;
return realObfuscator(value);
}
// ??? Throw exception? Return the original value?
}
专用只读字典混淆器=
新词典;
//或者,在构建时注册适当的模糊器。
公共无效注册表转换器(Func模糊器)
{
模糊器[类型(T)]=模糊器;
}
公共T混淆(T值)
{
委托模糊器;
if(模糊器.TryGetValue(类型(T),输出模糊器)
{
//我们知道这将是正确的类型。。。
var realObfuscator=(Func)模糊算子;
返回realObfuscator(值);
}
//?抛出异常?返回原始值?
}
您所展示的代码并不真正使用泛型,也不需要是泛型方法。您也可以轻松地进行模糊处理(IConvertible value)。方法中的代码不会更改,这通常是表明您没有真正使用泛型的一个关键标志。您指的是什么类型的处理?您不能做任何假设,除非您的类型是IConvertible
@marcGravel:但是在这种情况下,需要将方法调用返回转换为正确的类型。使用泛型方法确保返回类型正确。如果您所做的处理依赖于参数的类型,那么这可能不是泛型构造的好选择。如果处理只依赖于它是IConvertible的,那么您不需要进行类型检查。@RobertKoritnik啊,我没有看到返回类型;是的,这可能是一个重要因素,但是如果没有说明在…
中发生了什么,很难说您显示的代码没有真正使用泛型,也不需要它是泛型方法。您也可以很容易地让混淆(IConvertible值)
。方法中的代码不会更改,这通常是表明您没有真正使用泛型的一个关键标志。您指的是什么类型的处理?您不能做任何假设,除非您的类型是IConvertible
@marcGravel:但是在这种情况下,需要将方法调用返回转换为正确的类型。使用泛型方法确保返回类型正确。如果您所做的处理依赖于参数的类型,那么这可能不是泛型构造的好选择。如果处理只依赖于它是IConvertible的,那么您不需要进行类型检查。@RobertKoritnik啊,我没有看到返回类型;是的,这可能是一个重要因素,但是如果没有关于…
中发生了什么的指示,很难说是伟大的Jon!我曾考虑过使用带有类型
键的词典…但显然没有想到最后。但问题仍然是这种方法是否是最好的?有没有更好的方法提供相同的功能,但可能没有重新设计事先注册模糊处理程序?@RobertKoritnik:嗯,必须知道如何模糊处理int
vs模糊处理字符串
。你已经说过你不想在方法中使用这些信息……那么你想从哪里获得这些信息呢?好的。所以最好的方法可能是创建一个IObfuscator
接口并注册使用我的工厂模糊处理类(如图所示)将它们存储在静态字典中的单个模糊器(可重用性)?我只是想知道运行时是否有可能是我的工厂,所以我只想说someObj.Id=Obfuscate(someObj.Id)
和正确的模糊处理程序将被使用。@RobertKoritnik:为什么要有一个单独的接口?这对Func
有什么好处?是的,如果someObj.Id
的编译时类型是正确的,类型推断应该适用于您。TDD。假设一个定义void Obfuscate(模糊处理工厂)的基类
。继承它的子类。假设其中一个具有int-Id
和string-Name
属性。该类需要两个模糊器。调用obj.Obfuscate(factory)
的逻辑必须提供工厂,而obj
将调用工厂的Obfuscate(T值)
实际上混淆了它的值。TDD和可管理性指出,最好让混淆器实现一个接口,而不是在工厂中实现Func
。有些可能很复杂,最好封装在一个类中。我解释清楚了吗?太好了,Jon!我正在考虑使用带有类型
键的字典…但是应用程序显然没有想到最后。但问题仍然是这种方法是否最好?有没有更好的方法提供相同的功能,但可能不事先注册混淆器?@RobertKoritnik