簡體   English   中英

在C#中將類的對象作為參數傳遞

[英]Passing object of a class as parameter in C#

我想在 C# 中將 Class 對象作為參數傳遞,如下所示:

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");
}

您應該創建一些接口:

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");
}

並調用此方法是switch內的每種case

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

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

您要使用的所有類都必須實現一個接口。 例如像這樣:

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));
    }
}

我不會重復界面答案,我認為答案和評論中描述得足夠好。 我要提出的一點是在類構造函數中采用接口依賴項,而不是直接作為方法參數。

特別是在復雜的項目中,你有很多這樣的依賴項,我發現擁有(如果可能的話,不可變)類通過它們的構造函數獲取它們的依賴項而不是這些依賴項作為方法參數散布在它的方法中要干凈得多。 我發現它更干凈,更易於管理,更確定性和可測試性。 也更適合依賴注入並在中央對象組合根中創建對象。

另一個優點是更好的可用性,因為您的代碼的用戶不需要不斷地將接口傳遞給您的每個方法,他們在對象組合時向構造函數提供一次接口,然后在使用這些方法之后組合對象直接與實際問題相關的參數更多,無需傳入接口。

只是為了提供另一個選擇(除非絕對必要,否則我不會使用):

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

如果對象沒有calc方法,這可能會引發運行時異常,並且它肯定比使用接口(或反射,如果正確緩存)要慢......同樣,我不會使用它,但我給出了另一個選擇.

另一種可能性是使用繼承。 如果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";
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM