Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 对类型强制执行静态方法_C#_Inheritance_Polymorphism_Static Methods - Fatal编程技术网

C# 对类型强制执行静态方法

C# 对类型强制执行静态方法,c#,inheritance,polymorphism,static-methods,C#,Inheritance,Polymorphism,Static Methods,我希望一个类具有一个名为GetProduct的强制静态方法,以便客户端代码可以接受一个类型,并在检查传递的类型是否实现了名为ICommandThatHasProduct的接口后安全地调用该静态方法 这似乎是不可能的,所以现在我正在寻求帮助,寻找一种方法,我可以实现这一点。我知道我可以使用反射来查看传递给我的类型是否包含一个名为“GetProduct”的方法,但我希望有一种更面向对象的方法(即使用继承) 任何帮助都将不胜感激!下面的代码是伪c#,肯定不会编译 public interface IC

我希望一个类具有一个名为GetProduct的强制静态方法,以便客户端代码可以接受一个类型,并在检查传递的类型是否实现了名为ICommandThatHasProduct的接口后安全地调用该静态方法

这似乎是不可能的,所以现在我正在寻求帮助,寻找一种方法,我可以实现这一点。我知道我可以使用反射来查看传递给我的类型是否包含一个名为“GetProduct”的方法,但我希望有一种更面向对象的方法(即使用继承)

任何帮助都将不胜感激!下面的代码是伪c#,肯定不会编译

public interface ICommandThatHasProduct
{
    object GetProduct(int id);
}

public abstract class Command : ICommandThatHasProduct
{
    // I want to be able to make the GetProduct method static
    // so that calling code can safely call it
    public static object GetProduct(int id)
    {
        // do stuff with id to get the product
    }

    public object Execute()
    {
        CommandWillExecute();
    }

    public abstract object CommandWillExecute();
}

public class Program
{
    public Program(Type type, int productId)
    {
        if(type == ICommandThatHasProduct)
        {
            // Create the args
            var args = object[1]{ productId };

            // Invoke the GetProduct method and pass the args
            var product = type.InvokeMethod("GetProduct", args);

            //do stuff with product
        }

        throw new Execption("Cannot pass in a Command that does not implement ICommandHasProduct");
    }
}

方法不必是静态的。改为使用成员方法,并创建常用的继承树

我猜您正在寻找一个或一个简单的工厂方法模式在C#中的实现


记住。这有助于避免出现外观奇怪的继承树。

考虑到关于这是否是正确方法的评论,我假设您知道自己在做什么。下面是一个简单的代码示例:

using System;
using System.Reflection;

namespace EnforceStaticMethod
{
class Program
{
    static void Main()
    {
        var objA = GetProduct(typeof (TypeA), 1);
        var objB = GetProduct(typeof (TypeB), 2);

        Console.WriteLine("objA has type: " + objA.GetType());
        Console.WriteLine("objB has type: " + objB.GetType());
    }

    static object GetProduct(Type type, int id)
    {
        var argTypes = new[] {typeof (int)};
        var method = type.GetMethod("GetProduct", BindingFlags.Static | BindingFlags.Public, null, argTypes, null);
        if (method == null)
        {
            throw new ArgumentException("Type does not have GetProduct method: " + type);
        }

        var args = new object[] {id};
        return method.Invoke(null, args);
    }
}

class TypeA
{
    public static object GetProduct(int id)
    {
        return new TypeA();
    }
}

class TypeB
{
    public static object GetProduct(int id)
    {
        return new TypeB();
    }
}
}
我希望一个类有一个名为GetProduct的强制静态方法,这样客户机代码就可以接受
类型
对象,并在检查传递的类型是否实现接口后安全地调用该静态方法

您将通过反射进行调用,因此您也必须通过反射执行。反射的全部要点是在运行时执行编译器无法验证的工作;如果您想要的是编译时验证,那么您使用的工具完全是错误的。如果编译时验证正是您想要的,那么不要使用专门设计用来破坏编译时验证的工具

我希望有一种更面向对象的方式(即使用继承)

您正在以面向对象的方式进行操作。面向对象是以对象的形式传递功能单元,并向它们发送“消息”(也称为方法调用),描述您希望对其执行的操作,并以后期绑定的方式分析这些“消息”。(通常后期绑定是以虚拟调用的形式进行的,但按名称进行后期绑定也可以。)


继承是类之间共享代码和表示语义“是一种”关系的机制;为什么您觉得继承与您的问题相关?

为什么需要静态地调用它?您可以这样做:

public class Client 
{
    public void DoSomethingWith<T>() where T : ICommandThatHasProduct, new()
    {
        var command = new T();
        var products = command.GetProducts();
    }
}

您总是可以将实例而不是类型传递给客户端。

我认为您真正的问题是,您传递的是
类型而不是您自己的类。
GetProduct()
-方法实际上属于表示命令类型的类,但当然不能在实际的
类型上添加该方法。因此,您可以创建自己的类来表示命令的类型

我猜您正在使用
类型
s通过反射构造实际的
命令
s。如果是这样,你实际上想要一个“工厂”。(如果创建工厂没有意义,只需创建一个“CommandType”对象即可)

试着这样做:

public interface IFactory{
  object Create();
}

public interface IFactoryThatHasProduct: IFactory
{
  object GetProduct(int id);
}

public class MyCommand
{
  //...
}

public class MyCommandFactory:IFactoryThatHasProduct
{
  object Create(){
    return new MyCommand();
  }

  object GetProduct(int id){
    return //TODO
  }
}

public class Program
{
  public Program(IFactory factory, int productId)
  {
    // consider just having the method take IFactoryThatHasProduct instead of IFactory
    if(factory is IFactoryThatHasProduct){
      var factoryThatHasProduct = (IFactoryThatHasProduct) factory;
      var product = factoryThatHasProduct.GetProduct(productId);
    }
    else{
      throw new Exception("Cannot pass in a factory that does not implement IFactoryThatHasProduct");
    }
  }
}

}

静态
方法并不真正适用于一般的OO概念。没有静态继承,因此反射可能是唯一可能复制的方法,几乎所有的方法都已经解决了这个问题。因为构造函数的实际实现非常繁重,我不想为了使用该方法而必须实例化它。如果你可以将该方法作为静态方法使用,你将不会使用构造函数中的任何东西,所以。。。只需将另一个类与该代码一起使用。它将增加粘结性并减少耦合。
public interface IFactory{
  object Create();
}

public interface IFactoryThatHasProduct: IFactory
{
  object GetProduct(int id);
}

public class MyCommand
{
  //...
}

public class MyCommandFactory:IFactoryThatHasProduct
{
  object Create(){
    return new MyCommand();
  }

  object GetProduct(int id){
    return //TODO
  }
}

public class Program
{
  public Program(IFactory factory, int productId)
  {
    // consider just having the method take IFactoryThatHasProduct instead of IFactory
    if(factory is IFactoryThatHasProduct){
      var factoryThatHasProduct = (IFactoryThatHasProduct) factory;
      var product = factoryThatHasProduct.GetProduct(productId);
    }
    else{
      throw new Exception("Cannot pass in a factory that does not implement IFactoryThatHasProduct");
    }
  }
}