gpt4 book ai didi

c# - 如何解决泛型方法中类型推断的局限性

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

我正在尝试实现用于转换 Tuple<Descendant> 对象的通用方法键入 Tuple<Ancestor> 的对象类型。我遇到了一个似乎是 C# 语言限制的问题。

using System;

namespace Samples
{
public static class TupleExtensions
{
public static Tuple<SuperOfT1> ToSuper<T1, SuperOfT1>(this Tuple<T1> target)
where T1 : SuperOfT1
{
return new Tuple<SuperOfT1>(target.Item1);
}
}

public interface Interface { }

public class Class : Interface { }

static class Program
{
static void Main()
{
var tupleWithClass = new Tuple<Class>(new Class());

// Next instruction lead the compilation to error. :( The compiler doesn't try to infer types if at least one of generic type arguments is explicitly declared.
var tupleWithInterfaceIncorrect = tupleWithClass.ToSuper<Interface>();

// Next instruction is correct. But it looks ugly.
var tupleWithInterfaceCorrect = tupleWithClass.ToSuper<Class, Interface>();

// The code I try to write in my software is even worse:
// I need to declare more types explicitly, because my actual tuple has more dimensions.
// var myTupleInProduction = tuple.ToSuper<Class1<T>, Class2<T>, Interface1<T>, Interface2<T>>();
// This code is VB.NET-like (too verbose). The problem is compounded by the fact that such code is used in many places.

// Can I rewrite my TupleExtensions to provide more laconic code like that:
// var myTupleInProduction = tuple.ToSuper<Interface1<T>, Interface2<T>>();

Console.ReadKey();
}
}
}

问题:

  1. 您是否知道如何使此代码正常工作(考虑代码示例中的重要注释)?
  2. 如果不是,那么您会推荐我如何解决这个问题?我想让代码简单明了。

最佳答案

假设我正确阅读了您的问题,您想要推断某些类型参数而不是其他类型参数。这意味着您需要已经处于某种上下文中,该上下文具有可以推断的类型参数,因此您可以指定其他类型参数。你可以这样做:

using System;

public interface Interface { }

public class Class : Interface { }


public sealed class TupleHelper<T1>
{
private readonly Tuple<T1> tuple;

internal TupleHelper(Tuple<T1> tuple)
{
this.tuple = tuple;
}

// Unfortunately you can't express the constraint the way
// round you want here...
public Tuple<TSuper1> Super<TSuper1>()
{
return new Tuple<TSuper1>((TSuper1) (object) tuple.Item1);
}
}

public static class TupleExtensions
{
public static TupleHelper<T1> To<T1>(this Tuple<T1> tuple)
{
return new TupleHelper<T1>(tuple);
}
}

class Test
{
static void Main()
{

Tuple<Class> tupleWithClass = new Tuple<Class>(new Class());

Tuple<Interface> tupleWithInterfaceIncorrect =
tupleWithClass.To().Super<Interface>();
}
}

...但这并没有给你想要的约束,因为你不能写where T1 : TSuper1

另一方面,您可以反转操作,如下所示:

using System;
using System.Net;

public interface Interface { }

public class Class : Interface { }

public static class TupleHelper<T1>
{
public static Tuple<T1> From<TDerived1>(Tuple<TDerived1> tuple)
where TDerived1 : T1
{
return new Tuple<T1>(tuple.Item1);
}
}

class Test
{
static void Main()
{

Tuple<Class> tupleWithClass = new Tuple<Class>(new Class());

Tuple<Interface> tupleWithInterfaceIncorrect =
TupleHelper<Interface>.From(tupleWithClass);
}
}

这对我来说看起来更简单 - 但它确实意味着您不能以“流畅”的方式编写它。

关于c# - 如何解决泛型方法中类型推断的局限性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7139548/

25 4 0
文章推荐: python - Django 管理员,自定义错误消息?
文章推荐: c++ - 如何获取gtest TYPED_TEST参数类型
文章推荐: python - 如何在 Django 中使用
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com