使用奇怪的重复模板模式时的返回类型

发布于 2024-12-15 13:03:17 字数 722 浏览 2 评论 0原文

我正在使用奇怪的重复模板模式 (CRTP)在我的 C# 项目中,但我遇到了一些问题。从上面的链接中截取的代码:

public abstract class Base<T> where T : Base<T>{
    public T FluentMethod() {
        return (T)(this); 
    }
}

public class Derived : Base<Derived> {
}

漂亮!当我尝试做这样的事情时,问题就出现了:

public class SomeClass
{
    Base<T> GetItem() { /* Definition */ };
}

SomeClass 应该能够返回基类的任何实现,但是当然 T 在这里没有意义,因为这是在另一个类中。使用 Derived 而不是 T 进行编译,但这不是我想要的,因为我也应该能够返回其他类型的项目,只要它们是从 Base 派生的。此外,GetItem() 可能会根据 SomeClass 对象的状态返回不同类型的对象,因此使 SomeClass 通用也不是解决方案。

我是否在这里遗漏了一些明显的东西,或者在使用 CRTP 时不能完成此操作?

I'm using the curiously recurring template pattern (CRTP) in my C# project, but I'm having some problems. Code snipped from the link above:

public abstract class Base<T> where T : Base<T>{
    public T FluentMethod() {
        return (T)(this); 
    }
}

public class Derived : Base<Derived> {
}

Beautiful! The problem arises when I try to do something like this:

public class SomeClass
{
    Base<T> GetItem() { /* Definition */ };
}

SomeClass should be able to return any implementation of the Base class, but of course T has no meaning here as this is in another class. Putting Derived instead of T compiles, but this isn't what I want, as I should be able to return items of other types too, as long as they derive from Base. Also, GetItem() might return different typed object depending on the state of the SomeClass object, so making SomeClass generic isn't the solution either.

Am I missing something obvious here, or can't this be done while using the CRTP?

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

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

发布评论

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

评论(2

偏闹i 2024-12-22 13:03:18

您必须将方法声明为通用:

using System;
public abstract class Base<T> where T : Base<T> {
    public T FluentMethod() {
        return (T)(this);
    }
}

public class Derived : Base<Derived> {
}

public class SomeClass {
    Base<T> GetItem<T>() where T : Base<T> {
        throw new NotImplementedException();
    }
}

要使其成为属性,您必须将类本身声明为通用:

public class SomeClass<T> where T : Base<T> {
    Base<T> GetItem {
        get { throw new NotImplementedException(); }
    }
}

You must declare the method as generic:

using System;
public abstract class Base<T> where T : Base<T> {
    public T FluentMethod() {
        return (T)(this);
    }
}

public class Derived : Base<Derived> {
}

public class SomeClass {
    Base<T> GetItem<T>() where T : Base<T> {
        throw new NotImplementedException();
    }
}

To make it a property you must declare the class itself as generic:

public class SomeClass<T> where T : Base<T> {
    Base<T> GetItem {
        get { throw new NotImplementedException(); }
    }
}
彡翼 2024-12-22 13:03:18

不要将公共方法设为泛型,否则类型声明会达到另一个层次。为不同的类型创建一个工厂类,例如“Derived GetDerivedItem()”

public class SomeClass {
    private Base<T> GetItem<T>() { /*implementation */ }

    public Derived GetDerivedItem() {
        return GetItem<Derived>();
    }
}

Don't make public method as generic, else type declaration reach another level. Make a factory class for different Types like "Derived GetDerivedItem()"

public class SomeClass {
    private Base<T> GetItem<T>() { /*implementation */ }

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