我想了解为什么下面的代码不起作用以及如何修复它。
如果T为double或long为什么T不接受double或long的转换?
private IList<T> GetGenericList<T>(//whatever you want of param...
) where T : double
{
IList<T> Result = new List<T>();
T Value = 2.5; // does not compile
Result.Add(Value);
return Result;
}
[UPDATE] 好的人不要紧张!让我明白你说的话! :)
c#中泛型的原理是什么?
如果我将de代码更改为以下示例? (开箱即用,这只是一个例子,请忽略de规则(if(isDouble),等等)
apt-get update
apt-get install -y python-software-properties
add-apt-repository -y ppa:ondrej/php
add-apt-repository -y ppa:ondrej/apache2
apt-get update
apt-get upgrade -y
apt-get install -y htop apache2 php5.6 php5.6-curl php5.6-mcrypt mongodb-org curl git
由于
答案 0 :(得分:1)
您的代码无效的原因有三个:
double
和long
,这是不可能的double
和long
不能用作通用约束,因为它们是密封的。double
隐式转换为未知类型前两个没有“修复”。最后一个的修复方法是首先转换为object
:
if (isDouble)
{
T Value = (T)(object)2.5; // does not compile
Result.Add(Value);
}
else
{
T Value = (T)(object)2; // does not compile
Result.Add(Value);
}
没有办法让方法按照您希望的方式完全工作,因为无法将T
限制为double
或{{1} }。您可以使用反射检查类型,如果它不是其中之一则抛出异常,但是在编译时无法强制执行该异常。
核心问题是您的代码不是通用的。真正的通用代码并不关心long
是什么(模数一些非常宽泛的参数,就像它必须实现一些接口一样)。 调用者可以确定T
是什么,而不是方法,因此基于实际类型的T
具有不同逻辑的任何内容通常都是代码味道。这似乎只是一个学习练习,但如果您在现实生活中需要此功能,我建议您使用两种不同的方法:
T
接下来,您可以将冗余代码重构为通用方法(在这种情况下,您不需要约束它,因为您从调用方法控制类型):
private IList<double> GetDoubleList()
{
IList<double> Result = new List<double>();
double Value = 2.5;
Result.Add(Value);
return Result;
}
private IList<long> GetLongList()
{
IList<long> Result = new List<long>();
long Value = 2;
Result.Add(Value);
return Result;
}
答案 1 :(得分:0)
isDouble在运行时被赋予一个值。无论分支如何,这两个赋值在编译时都必须有意义。
您正在尝试使用原则上无法完成的泛型。
答案 2 :(得分:0)
要回答您的回答,请参阅:Introduction to Generics (C# Programming Guide)
就目前您只想处理double
或long
的问题而言,您可以像D Stanley建议的那样做,只是对其他类型做一些事情。这是一个例子:
private IList<T> GetGenericList<T>()
{
Type parmType = typeof(T);
if (!parmType.Equals(typeof(double)) && !parmType.Equals(typeof(long)))
{
return null;
}
else
{
IList<T> Result = new List<T>();
if (parmType.Equals(typeof(double)))
{
T Value = (T)(object)2.5;
Result.Add(Value);
}
else
{
T Value = (T)(object)2L;
Result.Add(Value);
}
return Result;
}
}
现在,当我像这样使用它时:
List<double> lDbl = (List<double>)GetGenericList<double>();
List<long> lLng = (List<long>)GetGenericList<long>();
List<string> lStr = (List<string>)GetGenericList<string>();
我最终得到lDbl
和lLng
中的预期值,包括正确的数据类型。但是,lStr
设置为null
,因为这是我处理double
或long
以外的类型的方式。您可以轻松地在那里抛出异常。