定义类类型以调用泛型方法 [英] Define class type to calling a generic method

查看:100
本文介绍了定义类类型以调用泛型方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个名为IAuditable的界面,如下所示:

  public  界面 IAuditable 
{
string AuditSummary
{
获得;
}
string AuditDetails
{
get ;
}
}



AuditTrail类中的两个通用方法如下:

  public  T GetActualOldValue< T>() where  T:IAuditable 
{
return FromXElement< T>(OldValue);
}
public T GetActualNewValue< T>()其中 T:IAuditable
{
return FromXElement< T>(NewValue);
}



以及我有一个属性可以通过在运行时获取类来返回审计摘要,如下所示:

< pre lang =c#> public string AuditSummary
{
获取
{
如果(HasNewValue || HasOldValue)
{
string libraryVal = GetLibraryValue();
汇编汇编 = Assembly.Load(libraryVal);
foreach (类型 assembly .GetTypes())
{
if (type.IsClass == true
{
if (type.FullName.EndsWith( < span class =code-string>。 + ClassName))
{
/ * 这里我想调用GetActualNewValue< foundClass>()。AuditSummary
*或GetActualOldValue< foundClass>()。AuditSummary;
* /

}
}
}
}
返回 < span class =code-string> ;
}
}



如您所知,我们可以在特定图书馆的运行时找到课程,请注意我不想叫通用在运行时的方法,只想调用带有基础的泛型方法,换句话说,如何将特定类传递给GetActualNewValue< ...>()为T,

 AuditTrail auditTrail = AuditTrail.GetAuditTrail( 76 ); 
string summmary = auditTrail.GetActualOldValue< DTClient>()。AuditSummary;
string details = auditTrail.GetActualOldValue< DTClient>()。AuditDetails;



此代码工作完美但主要问题是DTClient必须在运行时找到并为GetActualValue定义为T.



全部谢谢。

解决方案

目前尚不清楚从哪种类型的集合中找到要在通用中使用的类型。如果这种方法合理与否,那就更不清楚了。由于某些原因,我对此表示怀疑。



但问题本身在技术上很简单。唯一的问题是:1)如果你找到一个以上的课程会怎么样? 2)你想在哪里获得课程的实例?实例化它?



但是,我们假设你已经有了一些类型,如果找到符合标准的第一类,你就停止搜索当你找到它时实例化它,它会非常简单。让我们假设你有一些程序集,你想要找到它声明的所有类型,并返回找到的第一个合适类型的实例。我们还需要一个假设:实现 IAuditable 的类型应该有一定的签名。在我的例子中,它将是无参数构造函数(最常见的情况):



 使用系统; 
使用 System.Reflection;

// ...

< span class =code-keyword> static IAuditable FindFirstAuditable(Assembly assembly ){
Type [] types = 组件 .GetTypes();
string interfaceName = typeof (IAuditable).FullName;
foreach (类型类型 类型){
类型interfaceType = type.GetInterface (interfaceName, false );
if (interfaceType == null 继续;
ConstructorInfo构造函数= type.GetConstructor(Type.EmptyTypes); // 不带参数的构造函数
if (构造函数== null 继续;
return (IAuditable)constructor.Invoke( null ); // 施放安全,
/ / 因为我们已经测试过接口已实现
} // < span class =code-comment> loop

return null ;
}





如果您只想要类型,可以返回类型,您可以调用 GetType()关于你拥有的对象。



正如你所看到的,假设太多了。而且,它可能很慢。但这是因为你的目标不够明确。我希望你能够理解你可以使用哪些技术并以你的方式做到这一点。我建议你认真检查你的做法。



-SA


I have an interface called IAuditable as follows:

public interface IAuditable
{
    string AuditSummary
    {
        get;
    }
    string AuditDetails
    {
        get;
    } 
}


And two generic method in AuditTrail class as follows:

public T GetActualOldValue<T>() where T : IAuditable
    {
        return FromXElement<T>(OldValue);
    }
    public T GetActualNewValue<T>() where T : IAuditable
    {
        return FromXElement<T>(NewValue);
    }


as well as i have one property to returning Audit Summary by getting a class at run time as follows:

public string AuditSummary
    {
        get
        {
            if (HasNewValue || HasOldValue)
            {
                string libraryVal = GetLibraryValue();
                Assembly assembly = Assembly.Load(libraryVal);
                foreach (Type type in assembly.GetTypes())
                {
                    if (type.IsClass == true)
                    {
                        if (type.FullName.EndsWith("." + ClassName))
                        {
                            /*Here i want to call GetActualNewValue<foundClass>().AuditSummary
                             * or GetActualOldValue<foundClass>().AuditSummary;
                             */
                        }
                   }
                }
            }
            return "";
        }
    }


As you know we can find class at run time in specific library, Please note i don't want to call a generic method at run time,just wanna call generic method with founded, in other words how can i pass a specific class to GetActualNewValue<...>() as T,

AuditTrail auditTrail = AuditTrail.GetAuditTrail(76);
string summmary = auditTrail.GetActualOldValue<DTClient>().AuditSummary;
string details = auditTrail.GetActualOldValue<DTClient>().AuditDetails;


This code work perfectly but the main problem is DTClient must find at run time and define as T for GetActualValue.

Thanks all.

解决方案

It's not clear where do you want to find the type to be used in the generic, from what set of types. It's even less clear if such approach is reasonable or not. By some reasons, I doubt it.

However, the problem itself is technically simple. The only problems are: 1) what happens if you find more then one class? 2) where do you want to get the instance of the class? instantiate it?

However, let's assume that you already have some set of types, you stop search if you find the first of types which satisfy the criterion, and you want to instantiate the type when you find it, it would be pretty simple. Let's also assume you have some assembly where you want to find all the types it declares and return the instance of the first suitable type found. We will also need one more assumption: the type implementing IAuditable should have some certain signature. In my example, it will be the parameterless constructor (most usual case):

using System;
using System.Reflection;

//...

static IAuditable FindFirstAuditable(Assembly assembly) {
    Type[] types = assembly.GetTypes();
    string interfaceName = typeof(IAuditable).FullName;
    foreach (Type type in types) {
        Type interfaceType = type.GetInterface(interfaceName, false);
        if (interfaceType == null) continue;
        ConstructorInfo constructor = type.GetConstructor(Type.EmptyTypes); // a constructor without parameters
        if (constructor == null) continue;
        return (IAuditable)constructor.Invoke(null); // the cast it safe,
                                                     // because we already tested that the interface is implemented
    } //loop
    return null;
}



If you want just the type, you can return the type instead, of you can call GetType() on the object you have.

As you can see, too many assumptions. Also, it could be slow. But this is because your goals are not clear enough. I hope it will be enough for you to understand what techniques you could use and do it in your way. And I would recommend you to seriously review your approach.

—SA


这篇关于定义类类型以调用泛型方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆