Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/336.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 以类型泛型/不可知的方式实现泛型方法的最佳方法_C#_Generics_Factory Method - Fatal编程技术网

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