什么是ref参数?它有什么不好的地方?

15

我面临的情况似乎只能通过使用引用参数来解决,然而这意味着要改变一个方法以始终接受引用参数,尽管我只需要引用参数提供的功能5%的时间。

这让我想到“哇,太疯狂了,一定要找其他方法”。我是不是很愚蠢?引用参数可能会导致什么问题?

编辑

需要进一步说明的细节,我认为它们与我的问题并不完全相关,但是我们来看看。

我想保存一个新实例(它将更新ID,稍后可能会使用),或检索与某些逻辑匹配并更新该实例,将其保存,然后更改新实例的引用以指向现有实例。

代码或许可以让问题更加清晰:

protected override void BeforeSave(Log entity)
{
    var newLog = entity;

    var existingLog = (from log in repository.All()
                           where log.Stuff == newLog.Stuff 
                                 && log.Id != newLog.Id
                           select log).SingleOrDefault();

    if (existingLog != null)
    {
        // update the time
        existingLog.SomeValue = entity.SomeValue;
        // remove the reference to the new entity
        entity = existingLog;
    }
}

// called from base class which usually does nothing before save
public void Save(TEntity entity)
{
    var report = validator.Validate(entity);

    if (report.ValidationPassed)
    {
        BeforeSave(entity);
        repository.Save(entity);
    }
    else
    {
        throw new ValidationException { Report = report };
    }
}

这是一个事实,我只会为基类的一个(目前)子类添加它,这样就阻止我使用重载(因为我必须复制Save方法)。 我还面临一个问题,即在这种情况下我需要强制他们使用ref版本,否则事情不会按预期工作。


你能否给我们更多关于你正在做的事情的细节? - Szymon Rozga
1
考虑到你的方法目前返回的是void,为什么不将其改为返回实体呢? - Jon Skeet
因为这样做似乎不太对。我正在通过NHibernate持久化一个实体。返回已保存的对象(95%的情况下将是完全相同的对象)似乎毫无意义。虽然这样可以工作,但这正是我试图通过使用ref避免的。我想我陷入了自我批评的漩涡中! - Garry Shutler
12个回答

0

这是F#或其他函数式编程语言通过返回元组值更好地解决的问题之一。它具有更清晰简洁的语法。在我正在阅读的F#书中,它实际上指出了使用ref的C#等效方式,以在C#中返回多个参数。

我不知道是否存在关于ref参数的某些潜在“booga booga”或者它是一种不好的做法,对我来说,它们只是感觉不够简洁。


0
一个只有一个引用参数的无返回值函数对我来说确实看起来很有趣。 如果我正在审查这段代码,我会建议重构BeforeSave()以包括对Repository.Save()的调用 - 当然要改名字。 为什么不只有一个方法,它接受您可能的新实体并保证一切正确保存? 调用者无论如何都不会与返回的实体进行任何操作。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接