Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/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#_Oop_Inheritance_Dynamic_Abstract - Fatal编程技术网

使用动态类对象-C#

使用动态类对象-C#,c#,oop,inheritance,dynamic,abstract,C#,Oop,Inheritance,Dynamic,Abstract,有两种不同的服务。这些服务有不同的过程,但给我们相同的结果。助手方法需要使用该服务和服务响应。用户将选择要使用的服务。所以,我将创建一个helper方法,它接受所选的服务及其参数。问题是服务需要不同大小的不同参数(其中一些是常见的,但不是大多数) 我创建了一个抽象类,然后从中继承了两个类抽象类包含标准的方法。但是继承的类方法需要不同的类型和大小参数。因此,我计划使用动态类对象作为参数。这是正确的解决方案吗 public abstract class ServiceBase { publi

有两种不同的服务。这些服务有不同的过程,但给我们相同的结果。助手方法需要使用该服务和服务响应。用户将选择要使用的服务。所以,我将创建一个helper方法,它接受所选的服务及其参数。问题是服务需要不同大小的不同参数(其中一些是常见的,但不是大多数)

我创建了一个
抽象类
,然后从中继承了
两个类<代码>抽象类
包含标准的
方法
。但是
继承的类方法
需要不同的类型和大小参数。因此,我计划使用动态类对象作为参数。这是正确的解决方案吗

public abstract class ServiceBase
{
    public abstract int StandartMethod(dynamic parameters);
}

public class ServiceForA : ServiceBase
{
    public override int StandartMethod(dynamic parameters)
    {
        //Service Request is send to ServiceA with spesific parameters
        //(parameters.Ticket, parameter.myType1, string p1 , int n1, ..)
        //----
        //Service Response received and processed
        return requiredInfo;
    }
}

public class ServiceForB : ServiceBase
{
    public override int StandartMethod(dynamic parameters)
    {
        //Service Request is send to ServiceB with spesific parameters
        //(parameters.UserName,parameters.Password, parameters.myType1,int beginRange, ..)
        //----
        //Service Response received and processed
        return requiredInfo;
    }
}

public static int HelperMethod(ServiceBase service, ServiceParameters parameters)
{
   //Do required stuff
   return service.StandartMethod(parameters);
}

static void Main(string[] args)
        {
            ServiceBase serviceA = new ServiceForA();

            dynamic obj1 = new ServiceParameters();

            obj1.Ticket = GetTicket(UserName,Pass);
            obj1.p1 = "Parameter1";
            obj1.n1 = 10;

            var result = HelperMethod(serviceA, obj1);

            Console.WriteLine("RESULT 1: " + result);

            ServiceBase serviceB = new ServiceForB();

            dynamic obj2 = new ServiceParameters();
            obj2.UserName = "slyn";
            obj2.Password = "****";
            ...
            obj2.beginRange = 1;


            var result2 = HelperMethod(serviceB, obj2);

            Console.WriteLine("RESULT2: " + result2);

        }
Service
对象类型将为ServiceForA或ServiceForB。没关系,
StandartMethod
在这两个类中都实现了。而ServiceParameters类继承自
System.Dynamic.DynamicObject

似乎解决了问题,但这是正确的解决方案吗? 有什么建议吗?

通常您会为此使用泛型:

public abstract class ServiceBase<TArgs>
{
    public abstract int StandardMethod(TArgs args);
}

public class Arguments
{
     public string Text { get; set; }
     public int Number { get; set; }
}

public class ServiceForB : ServiceBase<Arguments>
{
    public override int StandardMethod(Arguments arguments)
    {
        // Thanks to generics, arguments are strongly-typed and
        // and you can access its properties as usual!
        string text = arguments.Text;
        int number = arguments.Number;

        return 0;
    }
}
公共抽象类ServiceBase
{
公共摘要国际标准方法(TArgs args);
}
公共类参数
{
公共字符串文本{get;set;}
公共整数{get;set;}
}
公共类ServiceForB:ServiceBase
{
公共重写int-StandardMethod(参数)
{
//由于有了泛型,参数是强类型的,并且
//您可以像往常一样访问它的属性!
字符串文本=参数;
int number=arguments.number;
返回0;
}
}
顺便说一句,这种方法可能存在一个问题:如果您需要另一个方法作为抽象类的一部分来支持相同的场景,该怎么办?最终会为它们中的每一个提供许多泛型类型参数。无论如何,正如您所说的,您的问题只是一种方法,这应该可以很好地解决。

通常您会为此使用泛型:

public abstract class ServiceBase<TArgs>
{
    public abstract int StandardMethod(TArgs args);
}

public class Arguments
{
     public string Text { get; set; }
     public int Number { get; set; }
}

public class ServiceForB : ServiceBase<Arguments>
{
    public override int StandardMethod(Arguments arguments)
    {
        // Thanks to generics, arguments are strongly-typed and
        // and you can access its properties as usual!
        string text = arguments.Text;
        int number = arguments.Number;

        return 0;
    }
}
公共抽象类ServiceBase
{
公共摘要国际标准方法(TArgs args);
}
公共类参数
{
公共字符串文本{get;set;}
公共整数{get;set;}
}
公共类ServiceForB:ServiceBase
{
公共重写int-StandardMethod(参数)
{
//由于有了泛型,参数是强类型的,并且
//您可以像往常一样访问它的属性!
字符串文本=参数;
int number=arguments.number;
返回0;
}
}

顺便说一句,这种方法可能存在一个问题:如果您需要另一个方法作为抽象类的一部分来支持相同的场景,该怎么办?最终会为它们中的每一个提供许多泛型类型参数。无论如何,正如您所说的,您的问题只是一种方法,这应该可以正常工作。

在运行时使用
策略模式
,您正在根据用户选择更改策略(因为两者都产生相同的结果)。如果要将基础服务实现公开给
public

public interface ICaller{
    int DoStuff(dynamic parameters);
}
internal class ServiceForA : ICaller
{
    internal int DoStuff(dynamic parameters)
    {
       //implementation       
    }
}
internal class ServiceForB : ICaller
{
    internal int DoStuff(dynamic parameters)
    {
       //implementation
    }
}
public class ServiceProcessor 
{
    private ICaller _service;
    public ServiceProcessor(ICaller service)
    {
        _service = service;
    }
    public int Invoke(ICaller service)
    {
        return _service.DoStuff(dynamic parameters);
    }
}
static void Main()
{
    var processor = new ServiceProcessor(new ServiceForA());
    processor.Invoke();
    var processor = new ServiceProcessor(new ServiceForB());
    processor.Invoke();
}

在运行时使用
策略模式
可以根据用户选择更改策略(因为两者产生相同的结果)。如果要将基础服务实现公开给
public

public interface ICaller{
    int DoStuff(dynamic parameters);
}
internal class ServiceForA : ICaller
{
    internal int DoStuff(dynamic parameters)
    {
       //implementation       
    }
}
internal class ServiceForB : ICaller
{
    internal int DoStuff(dynamic parameters)
    {
       //implementation
    }
}
public class ServiceProcessor 
{
    private ICaller _service;
    public ServiceProcessor(ICaller service)
    {
        _service = service;
    }
    public int Invoke(ICaller service)
    {
        return _service.DoStuff(dynamic parameters);
    }
}
static void Main()
{
    var processor = new ServiceProcessor(new ServiceForA());
    processor.Invoke();
    var processor = new ServiceProcessor(new ServiceForB());
    processor.Invoke();
}

否,您使用运算符检查类型,然后将类强制转换为具体类型并修改其参数。如果我从方法定义中删除
动态参数
,将不再有抽象类(重写的抽象方法需要相同的参数)。我需要在方法定义中写入实际参数。(在我们的示例中,ServiceForA和ServiceForB不是从ServiceBase获得的,StandartsMethods在ServiceFor*类中获取参数。)之后,为什么我需要强制转换类和修改参数?嗨@john,我的基本问题是一个抽象方法应该用不同的参数实现。有什么方法可以实现这种类型吗?没有,您可以使用运算符检查类型,然后将类强制转换为具体类型并修改其参数。如果我从方法定义中删除
动态参数
,将不再有抽象类(重写的抽象方法需要相同的参数)。我需要在方法定义中写入实际参数。(在我们的示例中,ServiceForA和ServiceForB不是从ServiceBase获得的,StandartsMethods在ServiceFor*类中获取参数。)之后,为什么我需要强制转换类和修改参数?嗨@john,我的基本问题是一个抽象方法应该用不同的参数实现。有什么办法可以实现这样的目标吗?