C# 在C中作为参数传递类的对象#

C# 在C中作为参数传递类的对象#,c#,c#-4.0,C#,C# 4.0,我想在C#中将类对象作为参数传递,如下所示: case "Case1": class obj1 = new class (); string abc = obj1.calc("100"); break; case "Case2": class2 obj2 = new class2 (); string abc = obj2.calc("100"); break; 因此,我不想调用obj1.calc和obj2.calc,而是希望将对

我想在C#中将类对象作为参数传递,如下所示:

case "Case1":

    class obj1 = new class ();

    string abc = obj1.calc("100");
    break;

case "Case2":

     class2 obj2 = new class2 ();

     string abc = obj2.calc("100");
     break;
因此,我不想调用obj1.calc和obj2.calc,而是希望将对象obj1作为写入计算逻辑的方法参数传递

public static void ProcessModel(object Model)
{
    String abc = <oBJECT>.calc("100");
}
publicstaticvoidprocessmodel(对象模型)
{
字符串abc=.calc(“100”);
}

要使用的所有类都必须实现一个接口。例如:

interface ICalculateable
{
    string calc (string value);
}
然后用…将这些实现到类中

class Class1 : ICalculateable
在方法中,使用接口作为参数:

public static string ProcessModel(ICalculateable Model, string value)
{
    return Model.calc(value);
}

要使用的所有类都必须实现一个接口。例如:

interface ICalculateable
{
    string calc (string value);
}
然后用…将这些实现到类中

class Class1 : ICalculateable
在方法中,使用接口作为参数:

public static string ProcessModel(ICalculateable Model, string value)
{
    return Model.calc(value);
}

为类提供一个接口,如下面的示例

IObject
继承的所有类必须具有
calc()
方法

public class Program
{
    public interface IObject
    {
        float calc();
    }

    public class ObjectA : IObject
    {
        public float calc() { return 5*3;}
    }

    public class ObjectB : IObject
    {
        public float calc() { return 8*7;}
    }

    private static float DoCalc(IObject obj)
    {
        return obj.calc();
    }

    public static void Main(string[] args)
    {
        IObject objA = new ObjectA();
        IObject objB = new ObjectB();

        Console.WriteLine(DoCalc(objA));
        Console.WriteLine(DoCalc(objB));
    }
}

为类提供一个接口,如下面的示例

IObject
继承的所有类必须具有
calc()
方法

public class Program
{
    public interface IObject
    {
        float calc();
    }

    public class ObjectA : IObject
    {
        public float calc() { return 5*3;}
    }

    public class ObjectB : IObject
    {
        public float calc() { return 8*7;}
    }

    private static float DoCalc(IObject obj)
    {
        return obj.calc();
    }

    public static void Main(string[] args)
    {
        IObject objA = new ObjectA();
        IObject objB = new ObjectB();

        Console.WriteLine(DoCalc(objA));
        Console.WriteLine(DoCalc(objB));
    }
}

您应该创建一些接口:

public interface ISomeInterface
{
    string calc(string str);
}
然后通过您的类实现它:

public class Class1 : ISomeInterface
{
    //your code
}    

public class Class2 : ISomeInterface
{
    //your code    
}
然后将方法
ProcessModel()
更改为:

public static void ProcessModel(ISomeInterface model)
{
    String abc = model.calc("100");
}

如果出于某种原因确实不想使用接口,可以使用反射。您的类应具有同名的方法:

public static string CallMethodOfSomeObject(object obj, string methodName, params object[] parameters)
{
    var type = obj.GetType();        
    var method = type.GetMethod(methodName, BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public);

    //use this if you use C#6 or higher version
    return (string)method?.Invoke(obj, parameters);

    //use this if you use C#5 or lower version
    if (method != null)
    {
        return (string)method.Invoke(obj, parameters);            
    }

    return null;       
}
以及您的方法
ProcessModel()

也可以考虑将<代码>进程模型()/<代码>返回类型> <代码>字符串 >:

public static string ProcessModel(ISomeInterface model)
{
    return model.calc("100");
}

//OR

public static string ProcessModel(object model)
{
    return CallMethodOfSomeObject(model, "calc", "100");
}
并在
开关内的每个
案例中调用此方法:

case "Case1":
    Class1 obj1 = new Class1 ();
    string abc = ProcessModel(obj1);
    break;

case "Case2":
     Class2 obj2 = new Class2 ();
     string abc = ProcessModel(obj2);
     break;

您应该创建一些接口:

public interface ISomeInterface
{
    string calc(string str);
}
然后通过您的类实现它:

public class Class1 : ISomeInterface
{
    //your code
}    

public class Class2 : ISomeInterface
{
    //your code    
}
然后将方法
ProcessModel()
更改为:

public static void ProcessModel(ISomeInterface model)
{
    String abc = model.calc("100");
}

如果出于某种原因确实不想使用接口,可以使用反射。您的类应具有同名的方法:

public static string CallMethodOfSomeObject(object obj, string methodName, params object[] parameters)
{
    var type = obj.GetType();        
    var method = type.GetMethod(methodName, BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public);

    //use this if you use C#6 or higher version
    return (string)method?.Invoke(obj, parameters);

    //use this if you use C#5 or lower version
    if (method != null)
    {
        return (string)method.Invoke(obj, parameters);            
    }

    return null;       
}
以及您的方法
ProcessModel()

也可以考虑将<代码>进程模型()/<代码>返回类型> <代码>字符串 >:

public static string ProcessModel(ISomeInterface model)
{
    return model.calc("100");
}

//OR

public static string ProcessModel(object model)
{
    return CallMethodOfSomeObject(model, "calc", "100");
}
并在
开关内的每个
案例中调用此方法:

case "Case1":
    Class1 obj1 = new Class1 ();
    string abc = ProcessModel(obj1);
    break;

case "Case2":
     Class2 obj2 = new Class2 ();
     string abc = ProcessModel(obj2);
     break;

我不会重复界面答案,我认为答案和评论中描述的已经足够好了。我想指出的一点是,在类构造函数中使用接口依赖项,而不是直接将其作为方法参数

特别是在复杂的项目中,您有许多依赖项,我发现通过构造函数获取依赖项的类(如果可能的话是不可变的)要比通过方法作为方法参数散布的依赖项干净得多。我发现这样做更干净、更易管理、更具确定性和可测试性。也更适合于依赖项注入和在中心对象组合根中创建对象


另一个优点是更好的可用性,因为代码的用户不需要不断地向每个方法传递接口,他们提供了接口一旦将对象组合到构造函数中,然后在使用组合对象的方法后,直接使用与实际问题更相关的参数,而无需在接口中传递。

我不会重复接口答案,我认为答案和注释中描述的已经够好了。我想指出的一点是,在类构造函数中使用接口依赖项,而不是直接将其作为方法参数

特别是在复杂的项目中,您有许多依赖项,我发现通过构造函数获取依赖项的类(如果可能的话是不可变的)要比通过方法作为方法参数散布的依赖项干净得多。我发现这样做更干净、更易管理、更具确定性和可测试性。也更适合于依赖项注入和在中心对象组合根中创建对象


另一个优点是更好的可用性,因为代码的用户不需要不断地向每个方法传递接口,他们提供了接口一旦将对象组合提交给构造函数,然后在使用组合对象的方法后,直接使用与实际问题更相关的参数,而无需传递接口。

仅给出另一个选项(除非严格必要,否则我不会使用):


如果对象没有
calc
方法,这可能会引发运行时异常,并且它肯定比使用接口(或反射,如果正确缓存)慢。。。同样,我不会使用这个,但我给出了另一个选项。

只是为了给出另一个选项(除非严格必要,否则我不会使用):


如果对象没有
calc
方法,这可能会引发运行时异常,并且它肯定比使用接口(或反射,如果正确缓存)慢。。。同样,我不会使用这个,但我给出了另一个选择。

另一种可能是使用继承。如果
calc
方法在两个类
class
class2
中执行相同的操作,则您只需在继承该方法的类中实现此方法一次:

public class C_Parent
{
    public virtual string calc(string s)
    {
        // do what ever you have to
        return "Result of parent";
    }
}

public class C1 : C_Parent
{        
}

public class C2 : C_Parent
{
}
然后,您的
ProcessModel
方法将
C\u父对象作为参数,并调用该方法
calc

public static void ProcessModel(C_Parent Model)
{
    String abc = Model.calc("100");
}
如果第二个类需要不同的实现,您可以重写
calc
方法。这样,将调用正确实现的
ProcessModel
方法:

public class C2 : C_Parent
{
    public override string calc(string s)
    {
        return "Result of C2 child";
    }
}

另一种可能是使用继承。如果
calc
方法在两个类
class
class2
中执行相同的操作,则您只需在继承该方法的类中实现此方法一次:

public class C_Parent
{
    public virtual string calc(string s)
    {
        // do what ever you have to
        return "Result of parent";
    }
}

public class C1 : C_Parent
{        
}

public class C2 : C_Parent
{
}
然后,您的
ProcessModel
方法将采用