簡體   English   中英

C#通用T類TypeOf,這可能嗎?

[英]C# Generic T Class TypeOf, is this possible?

我有一個通用的類。 Class<T>並且取決於調用代碼中的switch語句,它可以是class<int> class<string> class<decimal>

返回此方法的方法將其作為對象返回,因為調用代碼在設置之后才知道它是什么。

一旦我從函數取回對象,有沒有辦法做到這一點?

load(object result)
{
    Type t = result.GetType().GetGenericArguments()[0];

    Class<t> x = (Class<t>) result;
}

還是我必須設置一張支票來檢查每種類型的支票。 如果為int Class<int> ,等等。

編輯:

這是我想做的實際代碼:

public class ReportResult<TP>
{
    public ReportResult()
    {
        ReportHeaders = new List<ReportHeader>();
        ReportViews = new List<IDataAttributeChild<TP>>();
    }

    public List<ReportHeader> ReportHeaders {get;set;}
    public List<IDataAttributeChild<TP>> ReportViews {get;set;}         
}

BAL

    public object GetReportData(ReportProcedureNameEventArg procedureNameEventArg)
    {
        object result = null;

        switch (procedureNameEventArg.SelectedNode.Class)
        {
            case ReportClass.Count:
                var r = new ReportResult<int>
                            {
                                ReportViews = GetCountByReport(procedureNameEventArg),
                                ReportHeaders = GetReportHeaders(procedureNameEventArg.SelectedNode.ReportViewId)
                            };

                result = r;
                break;
            case ReportClass.List:
                break;
            case ReportClass.Date:
                 var r = new ReportResult<datetime>
                            {
                                ReportViews = GetDateSummaryReport(procedureNameEventArg),
                                ReportHeaders = GetReportHeaders(procedureNameEventArg.SelectedNode.ReportViewId)
                            };

                result = r;
                break;
            default:
                throw new ArgumentOutOfRangeException();
        }
        return result;
    }

圖形用戶界面

    public void LoadTreeResult(object result)
    {
        Type t = result.GetType().GetGenericArguments()[0];

        ReportResult<?> fff = (ReportResult<?>)result;


        dgResult.Columns.Clear();

        foreach (var header in result.ReportHeaders)
        {
            dgResult.Columns.Add(
                    new DataGridTextColumn
                    {
                        Header = header.Header,
                        Binding = new Binding(header.Binding)
                    });
        }

        // This would also be a switch depending on a property coming 
        // back to now what class to cast to in order to populate the grid.
        List<ReportCountByView> d = new List<ReportCountByView>();

        foreach (var reportCountByView in result.ReportViews)
        {
            d.Add((ReportCountByView)reportCountByView);
        } 

        dgResult.ItemsSource = d;
    }

如果可能的話,這是類模型的布局。

在此處輸入圖片說明

布局圖

謝謝。

如果您要在解決實例“ x”之后對實例x調用相同的操作,則可以考慮使用接口,這將允許您定義對象執行的方法(和屬性)而無需定義其類型。

您的代碼可能最終看起來像這樣

public interface IMyInterface
{
  void PerformOperation();
}

public class MyGeneric<T> : IMyInterface
{
  T Value {get;set;}
  MyGeneric(T val) 
  {
    Value = val;
  }

  void PerformOperation 
  { 
     Console.WriteLine("T is {0}", typeof(T));
     Console.WriteLine("Value is {0}", Value);
  }
}

public void main(string[] args)
{
   IMyInterface inst = null;
   switch (args[0])
   {
    case "string":
       inst = new MyGeneric("hello");
       break;
    case "int":
        inst = new MyGeneric(7);
        break;
    case "decimal"
        inst = new MyGeneric(18.9M);
        break;
    }

   inst.PerformOperation();
}

您以后想對x做什么? 另外,如果可以構造它,使x始終是某個基類的實例,則可以將其強制轉換為基類。

這取決於您以后打算如何使用泛型類型。 stringintdecimalobject以外沒有其他公共基類型,但是它們確實共享一些接口,因此如果以后要對其進行排序,則可以選擇Class<IComparable>東西。 或者,如果您想使用多個接口,則可以聲明通用約束:

Class<T> where T : IEquatable<T>, IComparable<T>, IFormattable // and so on...

但是,似乎您所要求的似乎是不可能的。 泛型的整個前提是在設計時設置類型。

我的意見

如果總是使用結果來調用類的相同成員,則可以創建一個接口並將其實現到不同的類,並將結果作為接口。 這樣,您將能夠使用不同的類,但可以在這些類中實現一些相同的接口成員

我認為進行此切換的最佳方法是為您的不同類型實際實現單獨的方法,然后在UI層進行切換。

例如

public ReportResult<int> GetReportDataCount(ReportProcedureNameEventArg procedureNameEventArg)

public ReportResult<DateTime> GetReportDataDate(ReportProcedureNameEventArg procedureNameEventArg)

public void GetReportDataList(ReportProcedureNameEventArg procedureNameEventArg)

“列表”是真正讓我失望的一個,因為它返回null,否則我會說要做一些類似public ReportResult<T> GetReportData<T>(ReportProcedureNameEventArg procedureNameEventArg) where T:struct (然后強制執行類型)編程)。

如果您想通過動力學來嘗試它,我想您可以通過使用ReportResult進行鴨子輸入來使它基本上那樣工作,但是在混合使用List模式時,它也可能會變得混亂。

暫無
暫無

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

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