C# 在方法中途添加泛型类型约束

C# 在方法中途添加泛型类型约束,c#,generics,C#,Generics,我有两种通用方法- public CustomObject<T> MethodA<T>(T arg1) where T : class { ... return MethodB<T>(arg1); } public CustomObject<R> MethodB<R>(R arg2) where R : class, IInterface { ... return new CustomObject&l

我有两种通用方法-

public CustomObject<T> MethodA<T>(T arg1) where T : class
{
    ...
    return MethodB<T>(arg1);
}


public CustomObject<R> MethodB<R>(R arg2) where R : class, IInterface
{
    ...
    return new CustomObject<R>();
}

很明显,这不会编译,但它应该编译,不是吗?我如何让编译器知道我知道
casted
实现了
IInterface
,并且是一个类,因此对
MethodB
的调用是可以的?这里最大的问题可能是我试图返回
CustomObject

,因为您的
CustomObject
是通用的,这是有问题的。例如,
CustomObject
不能与
CustomObject
互换,但您可以在两者之间进行转换

您可以将此作为一种解决方法:

public class CustomObject<T> where T : class {}
public interface IInterface { }

public static class CustomObjectConverter
{
    public static CustomObject<T1> ConvertTo<T1, T2>(CustomObject<T2> other)
        where T1 : class
        where T2 : class
    {
        return new CustomObject<T1>();
    }
}

public CustomObject<T> MethodA<T>(T arg1) where T : class
{
    if (arg1 is IInterface inf)
    {
        var b = MethodB(inf);
        return CustomObjectConverter.ConvertTo<T,IInterface>(b);
    }
    return null;
}
public CustomObject<T> MethodB<T>(T arg2) where T : class, IInterface
{
    return new CustomObject<T>();
}
公共类CustomObject,其中T:class{}
公共接口接口{}
公共静态类CustomObjectConverter
{
公共静态CustomObject ConvertTo(CustomObject其他)
其中T1:class
其中T2:类
{
返回新的CustomObject();
}
}
公共CustomObject方法A(T arg1),其中T:class
{
if(arg1是接口inf)
{
var b=方法b(inf);
返回CustomObjectConverter.ConvertTo(b);
}
返回null;
}
公共CustomObject方法B(T arg2),其中T:class,I接口
{
返回新的CustomObject();
}

您需要使用反射来实现此功能

试试这个:

public CustomObject<T> MethodA<T>(T arg1) where T : class
{
    if (arg1 is IInterface)
    {
        var method = this.GetType().GetMethod("MethodB").MakeGenericMethod(arg1.GetType());
        return (CustomObject<T>)method.Invoke(this, new [] { arg1 });
    }
    return null;
}
publiccustomobjectmethoda(T arg1),其中T:class
{
如果(arg1是接口)
{
var method=this.GetType().GetMethod(“MethodB”).MakeGenericMethod(arg1.GetType());
return(CustomObject)方法。Invoke(这是新的[]{arg1});
}
返回null;
}

哎呀,我把事情搞砸了。给我一分钟重写一下。你有两个选择。要么删除MethodB上的类约束,要么将IInterface约束添加到MethodB。幸运的是,在这种情况下,我无法执行这两种操作。无法在方法中“添加”T在此时实现接口的信息?请给出一些更具体的示例,说明为什么需要此结构?很难知道如果没有一个更熟悉的上下文来理解你的方法做什么,或者这些方法所在的类做什么,等等,是否会有一个完全不同但有效的答案@ErikE sure,情况是我有许多实体实现了一个接口“IActivatable”。这个界面包括两个道具-开始日期和结束日期。在创建/更新实体之前,我对它们运行适当的业务逻辑规则。在本例中,我想添加一些业务逻辑,对于实现IActivatable的每个实体,这些逻辑将检查开始日期是否早于结束日期。方法B就是那个检查。神秘性我喜欢这个答案,但@MineR's恰好对我的用例更有意义。这就是我接受他的原因。不过我很感谢你的帮助@尼克-米纳的解决方案不起作用。它使
MethodB
中的
R
始终是
i接口
,而不是对象的实际类型。请记住。。。反射是慢的。@ErikE-只有当反射太慢时才重要。而且速度似乎并不能阻止人们在代码中放入大量的
try
/
catch
块。只有当缓慢成为一个问题时,速度才是重要的。@Enigmativity我不是建议他不要使用反射。我是建议他记住它是缓慢的,而不是设计一个系统,当它增长并达到临界点时,过去可以接受的速度会变成一场噩梦。速度在某种程度上总是很重要的,因为速度是我们基本操作参数和SLA的一部分。如果知道这个方法将被多次调用,那么在这里进行这种反射是非常不明智的。部署时的应用程序可能只有1000个数据点,但在1年内它将有1000000个数据点。这是简单的计划淘汰。这不起作用,因为它使
MethodB
中的
t
始终
i界面
-它从来不是对象的实际类型。这与制作签名
customobjectmethodb(IInterface arg2)
谢谢。。。让我check@Nick我想他是对的,我不能删除我的答案,直到你不接受它。我不确定你应该删除它-这实际上对我有用。我能够将从MethodB返回的CustomObject转换为CustomObject。我不确定我是否理解Enigmativity的反对意见——尽管MethodB是“类”泛型约束,但我仍然能够调用它。好吧,这一点很好,我关于进行转换的说明是错误的。
public CustomObject<T> MethodA<T>(T arg1) where T : class
{
    if (arg1 is IInterface)
    {
        var method = this.GetType().GetMethod("MethodB").MakeGenericMethod(arg1.GetType());
        return (CustomObject<T>)method.Invoke(this, new [] { arg1 });
    }
    return null;
}