等价Java通用循环引用C#

等价Java通用循环引用C#,c#,generics,C#,Generics,我正在用C#移植一个Java库,发现了一个使用泛型循环引用的奇怪类: public static class UserAgentAnalyzerDirectBuilder<UAA extends UserAgentAnalyzerDirect, B extends UserAgentAnalyzerDirectBuilder<UAA, B>> { // Implementation } 公共静态类UserAgentAnalyzerDirectBuilder {

我正在用C#移植一个Java库,发现了一个使用泛型循环引用的奇怪类:

public static class UserAgentAnalyzerDirectBuilder<UAA extends UserAgentAnalyzerDirect, B extends UserAgentAnalyzerDirectBuilder<UAA, B>> 
{
   // Implementation
}
公共静态类UserAgentAnalyzerDirectBuilder
{
//实施
}
我不能很好地理解循环引用是如何工作的,但正如我所看到的,它确实是可能的

这段代码可以很容易地翻译成C#:

公共类UserAgentAnalyzerDirectBuilder其中UAA:UserAgentAnalyzerDirect其中B:UserAgentAnalyzerDirectBuilder
{
//实施
}
假设我的等价类是正确的,我需要实现实例化那个奇怪类的方法

在Java中,我有以下代码:

public static UserAgentAnalyzerDirectBuilder<? extends UserAgentAnalyzer, ? extends UserAgentAnalyzerDirectBuilder<?, ?>> newBuilder() {
    return new UserAgentAnalyzerDirectBuilder<>(new UserAgentAnalyzer());
}
publicstaticuseragentanalyzerdirectbuilder>newBuilder(){
返回新的UserAgentAnalyzerDirectBuilder(newuseragentanalyzer());
}
在C#中,我试图通过以下方式复制:

public static UserAgentAnalyzerDirectBuilder<UAA, UserAgentAnalyzerDirectBuilder<UAA, B>> newBuilder<UAA, B>() 
            where UAA: UserAgentAnalyzerDirect
            where B: UserAgentAnalyzerDirectBuilder<UAA, B>
        {
            return new UserAgentAnalyzerDirectBuilder<UAA, UserAgentAnalyzerDirectBuilder<UAA, B>> (new UserAgentAnalyzer());
        }
publicstaticuseragentanalyzerdirectbuilder newBuilder()
其中UAA:UserAgentAnalyzerDirect
其中B:UserAgentAnalyzerDirectBuilder
{
返回新的UserAgentAnalyzerDirectBuilder(newuseragentanalyzer());
}

但它不起作用。我想知道我是否做错了什么,或者在C#泛型中循环引用是否确实可能。

您看到的不是循环引用。类型参数约束只允许您传入一个类型,该类型是该约束指定的泛型类型的后代

下面的代码示例已编译,我认为可以满足您的需要:

public class UserAgentAnalyzerDirect { }

public class UserAgentAnalyzerDirectBuilder<UAA, B> 
    where UAA : UserAgentAnalyzerDirect 
    where B : UserAgentAnalyzerDirectBuilder<UAA, B>
{
    // this method is supposed to implement the effect of the 
    // constructor in the original Java code
    public void SetUAA(UAA a) { }

    // further implementation
}

public static UserAgentAnalyzerDirectBuilder<UAA, B> NewBuilder<UAA, B>()
    where UAA : UserAgentAnalyzerDirect, new()
    where B : UserAgentAnalyzerDirectBuilder<UAA, B>, new()
{
    // Unlike in Java, C# allows instantiating generic type parameters only using 
    // a parameter-less constructor. Hence we use the SetUAA method here instead.
    var a = new UAA();
    var b = new B();
    b.SetUAA(a);
    return b;
}
public类UserAgentAnalyzerDirect{}
公共类UserAgentAnalyzerDirectBuilder
其中UAA:UserAgentAnalyzerDirect
其中B:UserAgentAnalyzerDirectBuilder
{
//这种方法应该能够实现
//原始Java代码中的构造函数
公共无效SetUAA(UAA){}
//进一步实施
}
公共静态用户agentanalyzerdirectbuilder NewBuilder()
其中UAA:UserAgentAnalyzerDirect,new()
其中B:UserAgentAnalyzerDirectBuilder,new()
{
//与Java不同,C#只允许使用
//一个无参数的构造函数。因此我们在这里使用SetUAA方法。
var a=新的UAA();
var b=新的b();
b、 塞图阿(a);
返回b;
}
然后,您可以创建上述泛型类的自定义子体,如下所示:

public class CustomUserAgentAnalyzerDirect : UserAgentAnalyzerDirect { }

public class CustomUserAgentAnalyzerDirectBuilder : UserAgentAnalyzerDirectBuilder<CustomUserAgentAnalyzerDirect, CustomUserAgentAnalyzerDirectBuilder> { }
公共类CustomUserAgentAnalyzerDirect:UserAgentAnalyzerDirect{}
公共类CustomUserAgentAnalyzerDirectBuilder:UserAgentAnalyzerDirectBuilder{}

请澄清“它不工作”-这不是错误消息。第二个Java通用代码包含无界和
扩展的
通配符,这需要在C#上下文中进行类型变通。双无界通配符类型参数很少;我几乎看不到它在
extends
@Ondrej Tucny中使用。这是一个语法错误,我认为复制长消息是没有用的。如果将代码复制到前面,则可以看到代码在C#中无效。错误消息是通用的,包含对我的项目的特定引用,因此即使对于搜索和索引也没有意义,您能提供一个调用NewBuilder方法的示例吗?在Java中,我有UserAgentAnalyzerBuilder=UserAgentAnalyzer.newBuilder();我想在C#中唯一的方法就是使用继承类。
public class CustomUserAgentAnalyzerDirect : UserAgentAnalyzerDirect { }

public class CustomUserAgentAnalyzerDirectBuilder : UserAgentAnalyzerDirectBuilder<CustomUserAgentAnalyzerDirect, CustomUserAgentAnalyzerDirectBuilder> { }