C# C泛型:如果两个集合必须包含相同的类型,但集合不必是相同的类型,如何声明泛型

C# C泛型:如果两个集合必须包含相同的类型,但集合不必是相同的类型,如何声明泛型,c#,generics,C#,Generics,我需要T的类泛型签名,其中T必须是任何类型的IEnumerable,但IEnumerable中的可能不是 简言之: HashSet和HashSet是不允许的,但HashSet和List是允许的 我目前有以下签名: namespace Foo { public interface IOperator<in T, out TResult> { } public abstract class AbstractOperator<T, TOutput>

我需要T的类泛型签名,其中T必须是任何类型的IEnumerable,但IEnumerable中的可能不是

简言之: HashSet和HashSet是不允许的,但HashSet和List是允许的

我目前有以下签名:

namespace Foo {
        public interface IOperator<in T, out TResult> { }
        public abstract class AbstractOperator<T, TOutput> : IOperator<T, TOutput> { }
        public abstract class LogicalOperator<T> : AbstractOperator<T, bool> { }
        public sealed class IntersectionOperator<T> : LogicalOperator<T> where T : IEnumerable<T> { }
}
我有一个测试:

var op = new IntersectionOperator<HashSet<string>>(); //compile error
var setA = new HashSet<string> { "Hello", "World" };
var setB = new List<string> { "Goodbye", "World" };
            
Assert.True(op.Apply(setA, setB)); // compile error
第一个错误是:

Severity    Code    Description Project File    Line    Suppression State
Error   CS0311  The type 'System.Collections.Generic.HashSet<string>' cannot be used as type parameter 'T' in the generic type or method 'IntersectionOperator<T>'. There is no implicit reference conversion from 'System.Collections.Generic.HashSet<string>' to 'System.Collections.Generic.IEnumerable<System.Collections.Generic.HashSet<string>>'.    
Severity    Code    Description Project File    Line    Suppression State
Error   CS1503  Argument 2: cannot convert from 'System.Collections.Generic.List<string>' to 'System.Collections.Generic.HashSet<string>'   Gatekeeper.Test 
第二个错误是:

Severity    Code    Description Project File    Line    Suppression State
Error   CS0311  The type 'System.Collections.Generic.HashSet<string>' cannot be used as type parameter 'T' in the generic type or method 'IntersectionOperator<T>'. There is no implicit reference conversion from 'System.Collections.Generic.HashSet<string>' to 'System.Collections.Generic.IEnumerable<System.Collections.Generic.HashSet<string>>'.    
Severity    Code    Description Project File    Line    Suppression State
Error   CS1503  Argument 2: cannot convert from 'System.Collections.Generic.List<string>' to 'System.Collections.Generic.HashSet<string>'   Gatekeeper.Test 

这可以做到吗?

这是我唯一能做到的方法:

void Main()
{
    var op = new IntersectionOperator<string>();
    var setA = new HashSet<string> { "Hello", "World" };
    var setB = new List<string> { "Goodbye", "World" };

    bool result = op.Apply(setA, setB);
}

public interface IOperator<in T, out TResult> { TResult Apply(T x, T y); }
public abstract class AbstractOperator<T, TOutput> : IOperator<T, TOutput>
{
    public abstract TOutput Apply(T x, T y);
}
public abstract class LogicalOperator<T> : AbstractOperator<T, bool> { }
public sealed class IntersectionOperator<T> : LogicalOperator<IEnumerable<T>>
{
    public override bool Apply(IEnumerable<T> x, IEnumerable<T> y) =>
        x.Intersect(y).Any();
}

这是唯一对我有效的方法:

void Main()
{
    var op = new IntersectionOperator<string>();
    var setA = new HashSet<string> { "Hello", "World" };
    var setB = new List<string> { "Goodbye", "World" };

    bool result = op.Apply(setA, setB);
}

public interface IOperator<in T, out TResult> { TResult Apply(T x, T y); }
public abstract class AbstractOperator<T, TOutput> : IOperator<T, TOutput>
{
    public abstract TOutput Apply(T x, T y);
}
public abstract class LogicalOperator<T> : AbstractOperator<T, bool> { }
public sealed class IntersectionOperator<T> : LogicalOperator<IEnumerable<T>>
{
    public override bool Apply(IEnumerable<T> x, IEnumerable<T> y) =>
        x.Intersect(y).Any();
}

该类不需要IEnumerable约束,也不需要HashSet参数。然后将Apply的参数设置为IEnumerable,IEnumerable。您不能以您尝试的方式在C中创建约束。@CodeMaster-超级类型将接受任何2T,所以我不能这样做。@Enigmativity-所以,我只需要将其保留为object?我的意思是,这很好,因为底层实现的行为会正确。我看不到有两个泛型参数的超级类型。可能创建一个。该类不需要IEnumerable约束或HashSet参数,只需要。然后将Apply的参数设置为IEnumerable,IEnumerable。您不能以您尝试的方式在C中创建约束。@CodeMaster-超级类型将接受任何2T,所以我不能这样做。@Enigmativity-所以,我只需要将其保留为object?我的意思是,这很好,因为底层实现的行为会正确。我看不到有两个泛型参数的超级类型。也许创造一个新的世界。