c# - 具有嵌套泛型类型的方法
问题描述
我有一些类似的东西:
public class BaseClass
{
}
public class SimpleDerivedA : BaseClass
{
public void DoSomething() => Expression.Empty();
}
public class SimpleDerivedB : BaseClass
{
public void DoSomething() => Expression.Empty();
}
public class GenericDerived<T> : BaseClass where T : struct
{
public T data;
public void DoSomething<T>(T someParameter) => Expression.Empty();
}
public void Process<T, X>(T someObject, X someValue = default) where T : BaseClass where X : struct
{
switch (someObject)
{
case SimpleDerivedA a:
a.DoSomething();
break;
case SimpleDerivedB b:
b.DoSomething();
break;
case GenericDerived<X> g:
X obj = new X();
g.DoSomething(obj);
break;
}
}
Process 方法以一种丑陋的方式工作:
SimpleDerivedA a = new SimpleDerivedA();
SimpleDerivedB b = new SimpleDerivedB();
GenericDerived<Vector3> g = new GenericDerived<Vector3>();
Process(a, new int()); //second parameter is fake, just to be able to
call the method
Process(b, new int()); //second parameter is fake, just to be able to
call the method
Process(g, new Vector3());//second parameter is fake, just to be able to
call the method
理想情况下,我应该能够调用 Process(a), Process(b), Process(g)
就像是:
public void Process<T>(T someObject) where T: BaseClass where X: struct
{
switch (someObject)
{
case SimpleDerivedA a:
a.DoSomething();
break;
case SimpleDerivedB b:
b.DoSomething();
break;
case GenericDerived<X> g:
var obj = new X();
g.DoSomething(obj);
break;
}
}
或者:
public void Process<T<X>>(T someObject) where T : BaseClass where X : struct
{
switch (someObject)
{
case SimpleDerivedA a:
a.DoSomething();
break;
case SimpleDerivedB b:
b.DoSomething();
break;
case GenericDerived<X> g:
var obj = new X();
g.DoSomething(obj);
break;
}
}
这显然不编译。我需要在 API 中使用它,并且在GenericDerived<T>
有人使用它之前不会知道它的类型。
这里的问题是如何定义方法 Process 以便我可以使用三个派生类中的任何一个的实例作为参数,但只使用一个参数调用它,例如Process(value)
notProcess(value, fakeValue)
或Process<SomeType>(value)
?
解决方案
向基类添加接口。
interface IProcessable
{
void DoSomething(params object [] args);
}
public abstract class BaseClass : IProcessable
{
public abstract void DoSomething(params object[] args);
}
public class GenericDerived<T> : BaseClass where T : struct
{
public T data;
public override void DoSomething(params object[] args)
{
// optionally you can pass as many arguments as you like
data = (T)args.First();
}
}
然后你可以将你的对象传递给这样的方法。
public static void Process(IProcessable obj, params object[] args)
{
obj.DoSomething(args);
}
然后像这样从你需要的地方调用它
var a = new SimpleDerivedA();
var b = new SimpleDerivedB();
var c = new GenericDerived<T>();
Process(a);
Process(b);
Process(c, obj /* your struct T */);
推荐阅读
- r - 在 R 中,为什么将 ls 作为函数参数传递不同于将 ls() 作为函数参数传递?
- pandas - (Dask) 如何分配计算所需的昂贵资源?
- c# - 仅当我登录到公司域时才会出现 COM 异常
- sql - T-SQL 从包含值对的列表中获取一个
- micronaut - 带有普通 Hibernate JPA 的 Micronaut 1.0.RC1 在启动时失败
- node.js - 在公会成员上加倍越来越多
- jsonpath - JSON 路径无法与 athena 一起正常工作
- ios - 使用带有日期计算的谓词获取核心数据有时会崩溃
- python - 如何同时对多个图形应用选项
- unix - 如何在 csh unix 中运行依赖于另一个的作业