繁体   English   中英

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

[英]C# Generics: How can I declare a generic where 2 collections have to contain the same type but the collections needn't be of the same type

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

简而言之:永远不允许使用HashSet<int>HashSet<string> ,但允许使用HashSet<int>List<int>

我目前有这个签名:

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 

这能做到吗?

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

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();
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM