我在C#中有一个同时具有静态和非静态接口的类。在一个类中是否可能拥有相同名称和签名的静态和非静态方法?
当我尝试这样做时,编译器会报错,但是由于某种原因,我认为有一种方法可以实现这个。我错了吗?或者在同一个类中拥有静态和非静态方法是不可能的吗?
如果无法实现,是否有一种通用方法可以实现这样的需求?
编辑
从我收到的回复中,很明显这是不可能的。我将采用不同的命名系统来解决这个问题。
我在C#中有一个同时具有静态和非静态接口的类。在一个类中是否可能拥有相同名称和签名的静态和非静态方法?
当我尝试这样做时,编译器会报错,但是由于某种原因,我认为有一种方法可以实现这个。我错了吗?或者在同一个类中拥有静态和非静态方法是不可能的吗?
如果无法实现,是否有一种通用方法可以实现这样的需求?
编辑
从我收到的回复中,很明显这是不可能的。我将采用不同的命名系统来解决这个问题。
不可以。限制的原因是静态方法也可以在非静态上下文中调用,而无需在方法名称前加上类名(例如,使用 MyStaticMethod() 而不是 MyClass.MyStaticMethod())。如果同时存在静态和非静态方法,则编译器无法确定你要调用哪一个。
您可以拥有相同名称但具有不同参数的静态和非静态方法,遵循方法重载的相同规则,但它们不能具有完全相同的签名。
实际上,通过显式实现一个接口,有一种方法可以实现这个目的。这并不是完美的解决方案,但在某些情况下可以起作用。
interface IFoo
{
void Bar();
}
class Foo : IFoo
{
static void Bar()
{
}
void IFoo.Bar()
{
Bar();
}
}
有时候我在为P/Invoke调用编写包装类时会遇到这种情况。
(new Foo()).Bar();
时,出现错误:成员“Foo.Bar()”无法通过实例引用访问;请改为使用类型名称。
- T.Todua((IFoo)(new Foo())).Bar();
或者IFoo foo = new Foo(); foo.Bar();
。 - Richard您可以在实例方法中调用静态方法而无需指定类型名称:
class Foo
{
static void Bar()
{
}
void Fizz()
{
Bar();
}
}
……因此,有一个静态方法和一个实例方法使用相同的签名是不允许的,这是有道理的。
您想要实现什么?如果不知道具体情况,很难建议解决方法。我只会将其中一个方法重命名。
C#在这方面设计不够好...
虽然你可能想要全局或非全局的,但它应该默认选择一个,如果你想要另一个,那么你只需更加限定。
class Logger {
public static Logger instance;
public static void Log(string message) {
instance.Log(message); // currently the compiler thinks this is ambiguous, but really its not at all. Clearly we want the non-static method
}
public void Log(string message) {
}
public void DoStuff() {
Log("doing instance stuff"); // this could be ambiguous, but in my opinion it should default to a call to this.Log()
Logger.Log("doing global stuff"); // if you want the global qualify it explicitly
}
}
好的。这个问题的根源在于C#不应该让你在没有指定类型名称的情况下从实例方法中调用静态方法。
其他完全面向对象的语言(如Smalltalk)不允许这样做,对于理解对象的人来说也只会造成困惑。 实例和类(或静态)之间的分离非常重要,拥有一种促进这些细节混淆的语言......不是一个好主意......但这是我们从微软公司期望的类型的东西。
Adrian
你可以有相同名称的静态方法和实例方法,只要它们在参数的数量或类型上有所不同。这与您如何在类中拥有两个具有相同名称的实例方法是相同的规则。
尽管从技术上讲,在静态方法 vs 实例方法的情况下,它们已经通过实例方法中隐式的 this 参数存在差异,但该差异不足以让编译器确定您想要调用其中哪一个。
更新:我犯了一个错误。返回值不足以具有不同的签名。
public class Logger
{
public static Logger logger = new Logger();
public void Log(string? message)
{
Console.WriteLine(message);
}
public void LogStatic(string? message)
{
Log(message, null);
}
public static void Log(string? message, object? _ = null)
{
logger.Log(message);
}
}
.
static void Main(string[] args)
{
Logger.logger.Log("...");
Logger.logger.LogStatic("...");
Logger.Log("...");
}
Logger.logger.Log("...");
到底调用了哪个方法?),而且代码可读性较差,因为实际行为取决于了解编译器如何解析方法调用。这是一个相当聪明的解决方案,但我不建议在生产代码中使用。 - undefinedpublic class Foo
{
public static void DoSomething(int parameter)
{
Console.WriteLine(parameter.ToString());
}
}
public static class FooExtensions
{
public static void DoSomething(this Foo foo, int parameter)
{
Foo.DoSomething(parameter);
}
}