如何编写处理单个对象和集合的通用 Save() 方法?

发布于 2024-08-15 04:47:55 字数 400 浏览 2 评论 0原文

我在存储库类中有两个通用保存方法:

public void Save<T>(T entity)
{
    _session.Save(entity);
}

public void Save<T>(IEnumerable<T> entities)
{
    foreach (var item in entities)
    {
        _session.Save(item);
    }
}

但是,当我使用 Save(collection) (自动推断类型)时,它会将其识别为 T 而不是IEnumerable 并尝试使用第一种方法保存它。

如何编写此保存方法,以便它可以处理这两种情况,而无需显式提供类型?

I have two generic save methods in a repository class:

public void Save<T>(T entity)
{
    _session.Save(entity);
}

public void Save<T>(IEnumerable<T> entities)
{
    foreach (var item in entities)
    {
        _session.Save(item);
    }
}

However, when I use Save(collection) (which infers the type automatically), it recognizes it as a T rather than IEnumerable<T> and tries to save it using the first method.

How do I write this save method(s) so that it can handle either case, without me having to explicitly provide the type?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

爱给你人给你 2024-08-22 04:47:55

将类型参数放在存储库的类级别而不是方法级别,这样重载就不会含糊不清。

class Repo<T>
{
    public void Save(T entity)
    {
        _session.Save(entity);
    }

    public void Save(IEnumerable<T> entities)
    {
        foreach (var item in entities)
        {
            _session.Save(item);
        }
    }
}

你会像这样使用它:

var repo = new Repo<Person>();

var p = new Person();
repo.Save(p);

var ps = new Person[] { p };
repo.Save(ps);

Put the type parameter at the class level on your repository instead of at the method level, this way the overload will not be ambiguous.

class Repo<T>
{
    public void Save(T entity)
    {
        _session.Save(entity);
    }

    public void Save(IEnumerable<T> entities)
    {
        foreach (var item in entities)
        {
            _session.Save(item);
        }
    }
}

You'd use it like this:

var repo = new Repo<Person>();

var p = new Person();
repo.Save(p);

var ps = new Person[] { p };
repo.Save(ps);
や三分注定 2024-08-22 04:47:55

对于这种特定情况,您不能依赖类型推断。 (T) 将满足任何类型,因此推理不会继续搜索以查找仍满足签名的更具体约束。

You can't rely on type inference for this specific case. <T>(T) will satisfy any type, so the inference won't continue searching to find more specific constraints which still meet the signature.

淡紫姑娘! 2024-08-22 04:47:55

为什么要为重载方法烦恼呢?这样做不是更好吗:

public void Save<T>(T entity)
{
    if (T is IEnumerable)
    {
         foreach (var item in entity)
              _session..Save(item);
    } else  {
        _session.Save(entity);
    }
}

Whjy bother with overloaded methods?, isn't better to do it like:

public void Save<T>(T entity)
{
    if (T is IEnumerable)
    {
         foreach (var item in entity)
              _session..Save(item);
    } else  {
        _session.Save(entity);
    }
}
玩套路吗 2024-08-22 04:47:55

您也可以这样使用它:

    public void Save<T>(T entity)
    {
        if (typeof(T).GetInterfaces().Contains(typeof(IEnumerable)))
        {
            SaveEnumerable(entity as IEnumerable);
        }
        else
        {
            _session.Save(entity);
        }
    }

    public void SaveEnumerable(IEnumerable entities)
    {
        foreach (var item in entities)
        {
            _session.Save(item);
        }
    }

希望这有帮助!

You can use it like this also:

    public void Save<T>(T entity)
    {
        if (typeof(T).GetInterfaces().Contains(typeof(IEnumerable)))
        {
            SaveEnumerable(entity as IEnumerable);
        }
        else
        {
            _session.Save(entity);
        }
    }

    public void SaveEnumerable(IEnumerable entities)
    {
        foreach (var item in entities)
        {
            _session.Save(item);
        }
    }

Hope this helps!!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文