【问题标题】:how to get the class name at run time from a generic method that is in another class?如何在运行时从另一个类中的泛型方法获取类名?
【发布时间】:2020-06-20 07:53:02
【问题描述】:

我正在尝试使用 UriBuilder 生成我的 baseurl。我在我的 TestUtil 类中创建了一个通用的“GetRequestUrl”。如何在运行时使用此方法获取我的测试类的名称并附加到字符串 serviceAPI

//这是我的TestUtil类中的GetRequestUrl方法

public class TestUtil
{
        public string GetRequestUrl(string serviceName)
        {
            string serviceAPI = this.GetType().BaseType.Name;
            var requestUrl = new UriBuilder();
            requestUrl.Scheme = "http";
            requestUrl.Host = "svc-" + serviceName + "." + 
       ConfigurationManager.AppSettings["TestEnvironment"] + "-example.com/api/";
            requestUrl.Path = serviceAPI;
            Uri uri = requestUrl.Uri;

            return uri.ToString();

        }
}

//这是我的测试类,我希望在运行时将类名“TestClass”附加到 serviceAPI 字符串,但我得到的是 TestUtil。我试过关注..

this.GetType().Name;

this.GetType().BaseType.Name;

MethodBase.GetCurrentMethod().DeclaringType.Name;

public class TestClass
{
TestUtil util = new TestUtil();
    [Test]
    public void Method1()
{
     string fullUrl = util.GetRequestUrl("APIServiceName");

}

}

【问题讨论】:

    标签: c# api reflection nunit uribuilder


    【解决方案1】:

    您需要将一个类作为参数传递给 GetRequestUrl,或者您要附加的字符串。字符串更好,因为它可以防止您将来需要更改代码以采用不同的做法。要按照您想要的方式执行此操作,就是使用反射,如果您可以这样做,则应避免使用反射:

    公共类 TestUtil
    {
        公共字符串 GetRequestUrl(字符串 testType,字符串 serviceName)
        {
            字符串 serviceAPI = testType;
            var requestUrl = new UriBuilder();
            requestUrl.Scheme = "http";
            requestUrl.Host = "svc-" + serviceName + "."
            + ConfigurationManager.AppSettings["TestEnvironment"] + "-example.com/api/";
            requestUrl.Path = serviceAPI;
            uri uri = requestUrl.Uri;
    
            返回 uri.ToString();
        }
    }
    
    公共类TestClass
    {
        TestUtil util = new TestUtil();
        [测试]
        公共无效方法1()
        {
            string fullUrl = util.GetRequestUrl(this.GetType().ToString(), "APIServiceName");
        }
    }
    

    另一种选择是在构造函数中将其传入并将其存储为私有变量,该变量将数据集中起来,以便您只传入一次。使用接口优于使用类:

    使用接口方法:

    // 一个空的接口就可以了。
    // 然后 TestUtil 将需要一个 ServiceAPI 来使用它来创建它
    // 构造函数作为保证。
    公共接口 IServiceAPI { }
    
    使用 System.Reflection;
    公共类TestUtil
    {
        私人服务;
        
        // TestUtil 需要一个 ServiceAPI 类。
        公共 TestUtil(IServiceAPI 服务)
        {
            _service = 服务;
        }
        
        公共字符串 GetRequestUrl(字符串服务名称)
        {
            字符串 serviceAPI = _service.GetType().Name; // 获取类名。
            var requestUrl = new UriBuilder();
            requestUrl.Scheme = "http";
            requestUrl.Host = "svc-" + serviceName + "."
            + ConfigurationManager.AppSettings["TestEnvironment"]
            +“-example.com/api/”;
            requestUrl.Path = serviceAPI;
            uri uri = requestUrl.Uri;
    
            返回 uri.ToString();
        }
    }
    // 在 TestClass 上实现 IServiceAPI 接口。
    公共类TestClass:IServiceAPI
    {
        // 在这里使用“this”传入TestClass。
        TestUtil util = new TestUtil(this);
        
        [测试]
        公共无效方法1()
        {
            string fullUrl = util.GetRequestUrl("APIServiceName");
        }
    }
    

    【讨论】:

    • 我倾向于简单地传递 this 并让 TestUtil 类访问类型。
    • 如果你认为你的参数是一种API,传递字符串可以让你灵活地传递你想要的任何东西。如果你传递这个,你需要一个重载来改变它。如果你确实使用了这个,我会通过构造函数来代替。
    • 在构造函数中使用怎么办?我应该像这样在我的 Testutil 类中声明一个私有变量吗.. private string GetClassName() { return this.GetType().Name; }
    • 不完全是。创建一个构造函数TestUtil(TestClass testClass),将其保存到名为private _testClass 的私有属性中。我喜欢在私有属性后面加上下划线。然后你可以这样做string serviceAPI = _testClass.GetType().ToString();
    • 在该示例中,它将始终返回“TestClass”,因此您应该传入接口或基类型。但我不知道你的基类是什么,或者你是否使用继承类。接口是更好的选择,IMO。
    猜你喜欢
    • 2019-12-22
    • 2014-08-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-17
    • 1970-01-01
    • 1970-01-01
    • 2016-06-28
    相关资源
    最近更新 更多