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

时间:2017-02-13 10:32:31

标签: c# c#-4.0

我希望将Class对象作为参数传递给C#,如下所示:

{{1}}

所以我没有调用obj1.calc和obj2.calc,而是希望将对象obj1作为方法参数传递给写入计算逻辑。

{{1}}

6 个答案:

答案 0 :(得分:2)

您应该创建一些界面:

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 void ProcessModel(object model)
{
    String abc = CallMethodOfSomeObject(model, "calc", "100");
}

另外,请考虑将ProcessModel()返回类型更改为string

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

//OR

public static string ProcessModel(object model)
{
    return CallMethodOfSomeObject(model, "calc", "100");
}

并且case内的每个switch都会调用此方法:

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

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

答案 1 :(得分:1)

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

interface ICalculateable
{
    string calc (string value);
}

然后使用...

将它们实现到您的类中
class Class1 : ICalculateable

在您的方法中,使用接口作为参数:

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

答案 2 :(得分:1)

为您的课程提供一个界面,例如下面的例子。

所有继承自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));
    }
}

答案 3 :(得分:0)

我不会重复接口的答案,我认为在答案和评论中已经足够好了。我要说的一点是在类构造函数中采用接口依赖,而不是直接作为方法参数。

特别是在复杂的项目中,你有许多这些依赖项,我发现拥有(如果可能的话是不可变的)类更清晰,它们通过它们的构造函数来获取它们的依赖关系而不是通过它的方法作为方法参数传递这些依赖关系。我发现它更干净,更易于管理,更具确定性和可测试性。也更适合依赖注入和在中心对象组合根中创建对象。

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

答案 4 :(得分:0)

只是提供另一种选择(除非绝对必要,否则我不会使用):

public static void ProcessModel(dynamic Model)
{
  string abc = Model.calc("100");
  // ...
}

如果对象没有calc方法,这可能会抛出运行时异常,并且它肯定比使用接口慢(或者如果正确缓存则反射)...再次,我不会使用它,但是我给了另一种选择。

答案 5 :(得分:0)

另一种可能性是使用继承。如果calc方法在classclass2这两个类中都相同,那么您只需要在继承该方法的类中实现此方法一次:

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_Parent对象作为参数并调用方法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";
    }
}