【问题标题】:Inferring Type from a Type's Base Class in a Generic Class从泛型类中类型的基类推断类型
【发布时间】:2023-04-01 13:20:01
【问题描述】:

我知道标题可能有点令人困惑,但让我解释一下我要完成的工作..


假设我有

public class TestA<T>
{
    public T Key { get; set; }
}

还有

public class TestB : TestA<int>
{
    public string Name { get; set; }
}

如您所见,TestB 继承自 TestA&lt;int&gt;,因此继承了属性 public int Key


现在,让我们添加一个界面

public interface TestC<T> where T : TestA<X>
{
    T DoSomething(X argument);
}

这就是我遇到麻烦的地方。

我希望DoSomething 方法接受T (TestA&lt;&gt;) 的超类的任何类型的参数,在TestB 的情况下为int

所以,如果我有一个 TestC&lt;TestB&gt; 类型的实现,我希望 DoSomething 签名是:

public TestB DoSomething(int argument);

问题是TestA&lt;X&gt; 无法编译,我无法做到这一点


请问,您知道这是否可行吗?如果是这样,你能解释一下怎么做吗?

也许我可以用 Reflection 来管理一些事情?

【问题讨论】:

    标签: c# asp.net oop generics reflection


    【解决方案1】:

    您只需为缺少的类型添加通用参数,在本例中为X

    public interface TestC<T, X> where T : TestA<X>
    {
        T DoSomething(X argument);
    }
    

    【讨论】:

    • 为什么要添加到TestC,不明白
    • 我不想手动添加它并将其作为通用参数传递,我希望编译器推断它:(
    • @MatiCicero 你不能那样做。您需要手动指定。
    • @EhsanSajja 为什么不需要添加它?他想要有两种不同的泛型。为此,他需要定义两个通用参数。
    • @MatiCicero 那你拒绝听。它不会改变事实。
    【解决方案2】:

    也有一个可能的解决方案:

    public interface TestC {
        T DoSomething<T,X>(X x) where T : TestA<X>;
    }
    
    public class TestCImpl : TestC {
        public T DoSomething<T,X>(X x) where T : TestA<X>
            //Do something
            return default(T);
        }
    }
    

    这个可以编译,但很容易得到运行时异常,因为 IntelliSense 似乎不起作用并推断 x 参数的类型。

    例如,这两个都编译:

    TestC c = new TestCImpl();
    c.DoSomething<TestB>(2);
    c.DoSomething<TestB>("Hello");
    

    但只有第一个应该真正起作用,因为 TestB 继承自 TestA&lt;int&gt;

    【讨论】:

    • 1) 这不是 OP 要求的等效代码。 2) C# 永远不会推断出一些但不是所有的泛型参数。这是一个全有或全无的事情。您断言这些示例中的任何一个都可以编译是错误的,至少对于显示的代码而言。
    • 1) 它不是等效的,但它是编译问题的解决方法,因为我不需要明确指定参数或参数的类型
    • 不,它没有。如上所述,C# 永远不会推断出部分泛型参数列表,除此之外,您正在调用接口的构造函数。那当然永远不会编译。要让你的第二个 sn-p 编译 TextC 需要有一个与你所展示的完全不同的定义。您的第一个或第二个 sn-p 都可以编译,但它们不能一起编译。
    • 我告诉你是的
    • 那么要么你没有提供你正在使用的实际代码,你的代码尽管你的断言实际上并没有编译,或者你没有使用 C# 编译器。它将因错误而失败:Using the generic method 'TestC.DoSomething&lt;T,X&gt;(X)' requires 2 type arguments
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-09-17
    • 2012-09-23
    • 1970-01-01
    • 2018-01-18
    • 1970-01-01
    • 2018-05-15
    • 1970-01-01
    相关资源
    最近更新 更多