繁体   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