gpt4 book ai didi

c# - 将类泛型类型约束为元组

转载 作者:太空狗 更新时间:2023-10-29 20:47:34 25 4
gpt4 key购买 nike

  1. 我想创建一个具有一个通用 TKey 的类,其中 TKey 是 System.Tuple 之一可以创建的类型。

    public class Class1<TKey> where TKey : System.Tuple
    {
    /// Class Stuff Goes Here where TKey is one of the 8 tuple
    types found in the link in (1)

    }

我不太确定如何实现它。目标是防止我自己为每个元组类实现一个类。

最佳答案

你不能像其他人所说的那样,但你几乎可以做到。

所以所有的Tuple<...>类有这样的签名:

public class Tuple<T1, ...> : 
IStructuralEquatable,
IStructuralComparable,
IComparable,
ITuple

所有这些接口(interface)都保存 ITuple是公开的(ITuple 是一个内部接口(interface)),所以你可以尝试制作这样的东西:

public interface ITupleKey<TKey>
where TKey : IStructuralEquatable, IStructuralComparable, IComparable
{
}

“等等!”,你说,“我怎么能确定没有其他东西在实现这些接口(interface)?”

嗯,你不能。但正如我所说,这只是一种几乎的方式 - 幸运的是,IStructuralEquatableIStructuralComparable仅(自然地在框架级别)用于以下类型:

System.Array
System.Tuple<T1>
System.Tuple<T1,T2>
System.Tuple<T1,T2,T3>
System.Tuple<T1,T2,T3,T4>
System.Tuple<T1,T2,T3,T4,T5>
System.Tuple<T1,T2,T3,T4,T5,T6>
System.Tuple<T1,T2,T3,T4,T5,T6,T7>
System.Tuple<T1,T2,T3,T4,T5,T6,T7,TRest>

所以它非常接近。将其与运行时检查相结合 TKey实际上是 Tuple 的一些变体,您可能拥有所需的东西。

编辑:

一些基本用法:

public class Class1<TKey> 
where TKey : IStructuralEquatable, IStructuralComparable, IComparable
{
}

// will compile
var classTup1 = new Class1<Tuple<int>>();
var classTup2 = new Class1<Tuple<int,int>>();
var classTup3 = new Class1<Tuple<int,int,int>>();
var classTup4 = new Class1<Tuple<int,int,int,int>>();
var classTup5 = new Class1<Tuple<int,int,int,int,int>>();

// won't compile
var badclassTup1 = new Class1<int>();
var badclassTup2 = new Class1<string>();
var badclassTup3 = new Class1<object>();

而且,因为我显然已经疯了,让我们看看这里有什么可能:

public class Class1<TKey> 
where TKey : IStructuralEquatable, IStructuralComparable, IComparable
{
public Class1(TKey key)
{
Key = key;
TupleRank = typeof(TKey).GetGenericArguments().Count();
TupleSubtypes = typeof(TKey).GetGenericArguments();
Console.WriteLine("Key type is a Tuple (I think) with {0} elements", TupleRank);
TupleGetters =
Enumerable.Range(1, TupleRank)
.Select(i => typeof(TKey).GetProperty(string.Concat("Item",i.ToString())))
.Select(pi => pi.GetGetMethod())
.Select(getter => Delegate.CreateDelegate(
typeof(Func<>).MakeGenericType(getter.ReturnType),
this.Key,
getter))
.ToList();
}

public int TupleRank {get; private set;}
public IEnumerable<Type> TupleSubtypes {get; private set;}
public IList<Delegate> TupleGetters {get; private set;}
public TKey Key {get; private set;}

public object this[int rank]
{
get { return TupleGetters[rank].DynamicInvoke(null);}
}
public void DoSomethingUseful()
{
for(int i=0; i<TupleRank; i++)
{
Console.WriteLine("Key value for {0}:{1}", string.Concat("Item", i+1), this[i]);
}
}
}

测试装置:

var classTup1 = new Class1<Tuple<int>>(Tuple.Create(1));
var classTup2 = new Class1<Tuple<int,int>>(Tuple.Create(1,2));
var classTup3 = new Class1<Tuple<int,int,int>>(Tuple.Create(1,2,3));
var classTup4 = new Class1<Tuple<int,int,int,int>>(Tuple.Create(1,2,3,4));
var classTup5 = new Class1<Tuple<int,int,int,int,int>>(Tuple.Create(1,2,3,4,5));

classTup1.DoSomethingUseful();
classTup2.DoSomethingUseful();
classTup3.DoSomethingUseful();
classTup4.DoSomethingUseful();
classTup5.DoSomethingUseful();

输出:

Key type is a Tuple (I think) with 1 elements
Key type is a Tuple (I think) with 2 elements
Key type is a Tuple (I think) with 3 elements
Key type is a Tuple (I think) with 4 elements
Key type is a Tuple (I think) with 5 elements
Key value for Item1:1
Key value for Item1:1
Key value for Item2:2
Key value for Item1:1
Key value for Item2:2
Key value for Item3:3
Key value for Item1:1
Key value for Item2:2
Key value for Item3:3
Key value for Item4:4
Key value for Item1:1
Key value for Item2:2
Key value for Item3:3
Key value for Item4:4
Key value for Item5:5

关于c# - 将类泛型类型约束为元组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15578668/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com