接线员'?'不能应用于类型的操作数' T'

时间:2015-09-15 07:49:35

标签: c# generics delegates c#-6.0 null-propagation-operator

尝试使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单行。

3 个答案:

答案 0 :(得分:31)

由于并非所有内容都可以null,因此您必须将T缩小为可以为空的(即object)。结构不能为空,也不能枚举。

where上添加class可以解决问题:

public abstract class Feature<T> where T : class

那为什么它不起作用呢?

Invoke()会产生T。如果GetValuenull,则?运算符会将T类型的返回值设置为null,而不能T。例如,如果intint?,则无法使其成为可空(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来解决此问题。