约束类型特定类型 [英] Constrain type to specific types

查看:167
本文介绍了约束类型特定类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

是否可以限制特定类型的泛型方法

Is it possible to constrain a generic method on specific types?

我想写的东西是这样的:

I want to write something like this:

public T GetValue<T>(string _attributeValue) where T : float, string
{
    return default(T); // do some other stuff in reality
}



我大多只是试图避免有一个巨型的方法中开关语句或有如果指定了无效的类型抛出异常。

I'm mostly just trying to avoid having a giant switch statement inside the method or having to throw an exception if an invalid type is specified.

编辑:确认。我知道字符串是不是值类型。我开始了两个数字类型更早。对不起。

Ack. I knew string is not a value type. I started out with two numeric types earlier. Sorry.

推荐答案

您不能使用泛型约束来表达你感兴趣的限制。泛型并不意味着基于不相交的类型来表达的变化 - 他们的意思来表达则统一在一个类型的层次结构变化(或者那些实施某些接口)

You can't use generic constraints to express the limitations you are interested in. Generics are not meant to express variation based on disjoint types - they're meant to express variation that is unified over a hierarchy of types (or those implementing certain interfaces).

你有一些其它选择,但是。这取决于您选择的你想要做什么的确切性质。

You have a few alternative choices, however. Which you choose depends on the exact nature of what you're trying to do.

使用不同的命名方法来表达每个操作。我倾向于使用这种方法时,每一个方法是真正在做不同的东西。你可以说,从方法返回一个不同类型的值本质上是不同的操作,值得自己独特的名字。

Use differently named methods to express each operation. I tend to use this approach when each method is truly doing something different. You could argue that returning a different type of value from a method is essentially a different operation, and deserves its own unique name.

float GetFloat(string attrName) { }
string GetString(string attrName) { }

< STRONG>提供一个默认值,让类型推断。在许多设计中,你请求一个值的名字是很有用的提供一个默认值。这可以让你使用重载来区分它们之间的方法调用(基于默认值的类型)。不幸的是,这种做法是相当脆弱 - 而且很容易破坏传递文字值接受数字基元的过载(INT与UINT与长)时

Provide a "default value" to allow the type to be inferred. In many designs where you ask for a value by name it useful to supply a default value. This can allow you to employ overloading to differentiate between which method to invoke (based on the type of the default value). Unfortunately, this approach is quite fragile - and breaks easily when passing literal values to overloads that accept numeric primitives (int vs. uint vs. long).

float GetValue(string attrName, float defaultValue) { ... }
string GetValue(string attrName, string defaultValue) { ... }

使用一个通用的方法,而是抛出一个运行时异常,如果类型不是那些你支持的一个。我个人觉得这种丑陋的和违反仿制药的精神 - 仿制药要统一在一个层次或一组实施一些接口类型功能。然而,在某些情况下,它是有道理这样做(如果咱们这样一个特定类型不能支持,比方说)。这种方法的另一个问题是,一般的方法的签名不能从任何参数来推断,所以你必须指定所需调用它时......在这一点它也不遑多让(从一个语法点)类型。比有不同的方法名称

Use a generic method, but throw a runtime exception if the type isn't one of those you support. Personally I find this kind of ugly and in violation of the spirit of generics - generics should unify functionality over a hierarchy or a set of types implementing some interface. However, in some cases it makes sense to do so (if let's so one specific type cannot be supported, let's say). Another problem with this approach is that the signature of the generic method cannot be inferred from any parameters, so you would have to specify the type desired when calling it ... at which point it's not much better (from a syntax point of view) than having different method names.

T GetValue<T>( string attrName )
{
   if( typeof(T) != typeof(string) ||
       typeof(T) != typeof(float) )
       throw new NotSupportedException();
   return default(T); 
}

// call it by specifying the type expected...
float f = GetValue<float>(attrName);
string s = GetValue<string>(attrName);

使用out参数而不是一个返回值。:此方法效果好,但它失去了能够呼吁一个返回值的方法和行为,因为你首先要声明一个变量来填充简洁的语法。

Use an out parameter instead of a return value. This approach works well, but it loses the concise syntax of being able to call a method and act on a return value, since you first have to declare a variable to populate.

void GetValue( string attrName, out float value )
void GetValue( string attrName, out string value )

// example of usage:
float f;
GetValue( attrName, out f );
string s;
GetValue( attrName, out s );

这篇关于约束类型特定类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆