我有一个方法,我在具体类型和标记上重载,以便在泛型类型上使用[ObsoleteAttribute]
)编译时失败。
这样做的原因是确保该方法的任何调用者都将其专门用于目标类型。无法改变实际类型或层次结构;所以我需要使用ad-hoc方法来实现这个目标(下面static void CustomMethod
)。
以下是示例代码:
class Program
{
class MyClass { }
static void CustomMethod(MyClass m)
{
Console.WriteLine("m");
}
[ObsoleteAttribute("Unknown type", true)]
static void CustomMethod<T>(T m)
{
;
}
static void Invoke<T>(T input)
{
CustomMethod(input);
}
static void Main(string[] args)
{
// This should compile ok
MyClass m = new MyClass();
Invoke(m);
// This should fail compilation
Invoke("no CustomMethod() defined for me");
}
}
此操作因Error CS0619 'Program.CustomMethod<T>(T)' is obsolete: 'Unknown type'
使用C ++模板很容易实现这一点,因为编译器只将调用解析为实际的实例化类型而不是任何泛型类型T
是否有任何“编译时”方式使Invoke<T>()
工作?
注意:不使用C#dynamic
或反射来寻找解决方案。
答案 0 :(得分:1)
在您列出的限制条件中,除了为您想要Invoke
的每种类型创建单独的CustomMethod
重载之外,您实际上没有任何其他选项。
假设Invoke
不只是简单地调用CustomMethod
,您可以通过创建包装CustomMethod
的子类并处理基类中的常见内容来避免重复该公共代码:
class Program
{
class MyClass { }
class MyClass2 { }
// wrapper classes for CustomMethod for each type
class MyClassStrategy : Strategy<MyClass>
{
protected override void CustomMethod(MyClass t)
{
Console.WriteLine("MyClass");
}
}
class MyClass2Strategy : Strategy<MyClass2>
{
protected override void CustomMethod(MyClass2 t)
{
Console.WriteLine("MyClass2");
}
}
// base class for doing "common stuff"
abstract class Strategy<T>
{
protected abstract void CustomMethod(T t);
public virtual void Run(T t)
{
// do common stuff...
CustomMethod(t);
// do more common stuff...
}
}
// create an Invoke overload for each wrapper class
static void Invoke(MyClass m) { new MyClassStrategy().Run(m); }
static void Invoke(MyClass2 m2) { new MyClass2Strategy().Run(m2); }
static void Main(string[] args)
{
// These compile OK:
MyClass m = new MyClass();
Invoke(m);
MyClass2 m2 = new MyClass2();
Invoke(m2);
// This doesn't compile:
// (obviously, there are no Invoke overloads that take a string)
Invoke("sdfdsff");
}
}