尝试使Feature
通用,然后突然编译说
运营商'?'不能应用于“'
类型的操作数
这是代码
public abstract class Feature<T>
{
public T Value
{
get { return GetValue?.Invoke(); } // here is error
set { SetValue?.Invoke(value); }
}
public Func<T> GetValue { get; set; }
public Action<T> SetValue { get; set; }
}
可以使用此代码
get
{
if (GetValue != null)
return GetValue();
return default(T);
}
但我想知道如何修复那个漂亮的C#6.0单行。
答案 0 :(得分:31)
由于并非所有内容都可以null
,因此您必须将T
缩小为可以为空的(即object
)。结构不能为空,也不能枚举。
在where
上添加class
可以解决问题:
public abstract class Feature<T> where T : class
那为什么它不起作用呢?
Invoke()
会产生T
。如果GetValue
为null
,则?
运算符会将T
类型的返回值设置为null
,而不能T
。例如,如果int
为int?
,则无法使其成为可空(T
),因为所需的实际类型(int
= T
)不是&{ #39;吨
如果您在代码中将int
更改为get
{
int? x = GetValue?.Invoke();
return x.GetValueOrDefault(0);
}
,则会非常清楚地看到问题。你问的最终结果是:
default(T)
这不是零传播运算符将为您做的事情。如果您恢复使用func queryFromParse(){
var query = PFQuery(className: "currentUploads")
query.orderByDescending("createdAt")
query.findObjectsInBackgroundWithBlock { (objects:[AnyObject]?, error:NSError?) -> Void in
if error == nil
{
if let newObjects = objects as? [PFObject] {
for oneobject in newObjects {
let text = oneobject["imageText"] as! String
let username = oneobject["username"] as! String
let time = oneobject.createdAt!
if let userImage = oneobject["imageFile"] as? PFFile {
let userImage = oneobject["imageFile"] as! PFFile
let imageURL = userImage.url // <- Bruker nå userImage.URL, henter ikke bildefilen med en gang
var OneBigObject = Details(username: username, text: text, CreatedAt: time, image: imageURL!)
self.arrayOfDetails.append(OneBigObject)
dispatch_async(dispatch_get_main_queue()) { self.collectionView.reloadData() }
}
}
}
}
}
}
,它确实知道该做什么,并且您可以避免出现问题&#39;空传播。
答案 1 :(得分:8)
T
必须是引用类型或可空类型
public abstract class Feature<T> where T : class
{
// ...
}
答案 2 :(得分:4)
据我所知,?.
运算符是硬编码的,可以与null
一起使用,也就是说,它适用于引用类型或可空值类型,但不适用于 normal 值类型。如果表达式为null
而不是null
,则运算符可能会返回default(T)
。
您可以通过在此处将T
限制为class
来解决此问题。