【问题标题】:Restrict passing instances of derived classes as method parameters限制将派生类的实例作为方法参数传递
【发布时间】:2017-02-22 13:43:48
【问题描述】:

情况是这样的。我有一个类和一个派生类

public class MyClass
{  }

public class MyDerivedClass : MyClass
{  }

我还有一个方法(在外部类中),它以MyClass 的实例为参数:

public class AnotherClass {
  public void DoSomething(MyClass myClass) 
  { }
}

如何限制DoSomething 方法只接受MyClass 的实例,而不接受MyDerivedClass 的实例?

【问题讨论】:

  • 你为什么要这样做?
  • 你不能。您可以在运行时检查类型并抛出异常,但编译器无法阻止
  • 你要求的是反对面向对象的编程,MyDerivedClassMyClass。就像“我不想要车,但我想要一辆法拉利!”
  • @Esko,谢谢。这对我来说很有用,因为我不确定我是否做对了。我的问题很简单:我有一个类和一个派生类,它们共享相同的功能,但这些类的实例存储在不同的数据库中,我希望有不同的方法来操作那里的内容,而不是根据类型选择合适的数据库类的实例
  • @Esko 你的类比是相反的。这就像说,“我会接受任何存在的汽车,但我不接受法拉利。”

标签: c# .net


【解决方案1】:

如果这是您想要的,那么您需要自己检查代码是否是 Derived 类型,通过 Exception 告诉调用代码 Derived 此方法不允许使用类型对象:

public class AnotherClass {
  public void DoSomething(MyClass myClass) 
  { 
       if(myClass.GetType() != typeof(MyClass))
       {
          throw new Exception("Derived objects not allowed");
       }
  }
}

【讨论】:

  • 虽然我不推荐 OP 想要什么(原因与问题中的 cmets 相同),但这是满足 OP(不常见)请求的正确方法。
  • 如果这被认为是不推荐的做法,我应该将此答案标记为正确答案吗?
  • @AntonVoronin 如果它正在回答所提出的问题并且答案解决了该特定问题,那么接受它并没有什么坏处:)
【解决方案2】:

你在这里尝试做的更多是与所有编程语言中很常见的不变性问题有关。

表示只能使用最初指定的类型;所以一个 不变的泛型类型参数既不是协变的,也不是 逆变的。您不能分配 IEnumerable 的实例 (IEnumerable) 类型的变量 IEnumerable,反之亦然。

这是给你的参考https://msdn.microsoft.com/en-us/library/dd799517(v=vs.110).aspx

我的建议,尝试更改实现并将所有方法放入接口中,这应该更清楚

class Root: Interface
{
 ...implementation of your common methods
}

class Derived: Interface
{
  ...implementation of your common methods
  //this should just
  public void DoSomething(MyClass myClass)
}

如果您不想使用上述方法,请使用“as”运算符将您传递的参数视为 MyRootClass,var a = parameter as MyRootClass。如果 a 为 null,那么您没有将正确的值传递给方法,或者直接检查类型。

如果建议您阅读此主题:

http://amapplease.blogspot.com/2009/04/invariance-covariance-contravariance.html https://stackoverflow.com/a/13107168/819153 https://blogs.msdn.microsoft.com/ericlippert/2009/03/19/representation-and-identity/

希望对你有帮助

【讨论】:

    猜你喜欢
    • 2011-06-03
    • 2022-01-05
    • 1970-01-01
    • 2019-03-26
    • 2020-01-26
    • 2020-08-14
    • 1970-01-01
    • 2011-07-18
    • 1970-01-01
    相关资源
    最近更新 更多