草庐IT

java - .Net 等同于 Java 类型的 Class<>?

coder 2023-08-29 原文

我是 .NET 专家,所以让我先声明我对一些 Java 概念的理解 - 如果我错了请纠正我。

Java 泛型支持有界通配符的概念:

class GenericClass< ? extends IInterface> { ... }

...类似于 .NET where限制:

class GenericClass<T> where T: IInterface { ... }

Java 的 Class 类描述了一种类型,大致等同于 .NET Type

到目前为止,还不错。但是我找不到与 Java 通用类型 Class<T> 足够接近的等价物。其中 T 是有界通配符。这基本上对 Class 的类型施加了限制。代表。

让我举个 Java 的例子。

String custSortclassName = GetClassName(); //only known at runtime, 
                                           // e.g. it can come from a config file
Class<? extends IExternalSort> customClass 
    = Class.forName("MyExternalSort")
        .asSubclass(IExternalSort.class);  //this checks for correctness

IExternalSort impl = customClass.newInstance(); //look ma', no casting!

我在 .NET 中能得到的最接近的是这样的:

String custSortclassName = GetClassName(); //only known at runtime, 
                                           // e.g. it can come from a config file

Assembly assy = GetAssembly();             //unimportant 

Type customClass = assy.GetType(custSortclassName);
if(!customClass.IsSubclassOf(typeof(IExternalSort))){
    throw new InvalidOperationException(...);
}
IExternalSort impl = (IExternalSort)Activator.CreateInstance(customClass);

Java 版本对我来说看起来更干净。 有没有办法改进 .NET 对应物?

最佳答案

System.Type 使用扩展方法和自定义包装类,您可以非常接近 Java 语法。

注意: Type.IsSubclassOf 不能用于测试类型是否实现接口(interface) - 请参阅 MSDN 上的链接文档。可以使用 Type.IsAssignableFrom 相反 - 请参阅下面的代码。

using System;

class Type<T>
{
    readonly Type type;

    public Type(Type type)
    {
        // Check for the subtyping relation
        if (!typeof(T).IsAssignableFrom(type))
            throw new ArgumentException("The passed type must be a subtype of " + typeof(T).Name, "type");

        this.type = type;
    }

    public Type UnderlyingType
    {
        get { return this.type; }
    }
}

static class TypeExtensions
{
    public static Type<T> AsSubclass<T>(this System.Type type)
    {
        return new Type<T>(type);
    }
}

// This class can be expanded if needed
static class TypeWrapperExtensions
{
    public static T CreateInstance<T>(this Type<T> type)
    {
        return (T)Activator.CreateInstance(type.UnderlyingType);
    }
}

使用接口(interface)差异的进一步改进

(应仅在评估性能后在生产代码中使用。可以通过使用(并发!)缓存字典来改进 ConcurrentDictionary<System.Type, IType<object>)

使用 Covariant type parameters 、C# 4.0 引入的一个特性,以及一个附加类型 interface IType<out T> ,这Type<T>实现,可以使类似以下的事情成为可能:

// IExternalSortExtended is a fictional interface derived from IExternalSort
IType<IExternalSortExtended> extendedSort = ...
IType<IExternalSort> externalSort = extendedSort; // No casting here, too.

甚至可以这样做:

using System;

interface IType<out T>
{
    Type UnderlyingType { get; }
}

static class TypeExtensions
{
    private class Type<T> : IType<T>
    {
        public Type UnderlyingType
        {
            get { return typeof(T); }
        }
    }

    public static IType<T> AsSubclass<T>(this System.Type type)
    {
        return (IType<T>)Activator.CreateInstance(
           typeof(Type<>).MakeGenericType(type)
        );
    }
}

static class TypeWrapperExtensions
{
    public static T CreateInstance<T>(this IType<T> type)
    {
        return (T)Activator.CreateInstance(type.UnderlyingType);
    }
}

这样就可以(明确地)在不相关的接口(interface)之间转换 InterfaceAInterfaceB喜欢:

var x = typeof(ConcreteAB).AsSubclass<InterfaceA>();
var y = (IType<InterfaceB>)x;

但这有点违背了练习的目的。

关于java - .Net 等同于 Java 类型的 Class<>?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14237113/

有关java - .Net 等同于 Java 类型的 Class<>?的更多相关文章

  1. ruby-on-rails - Ruby net/ldap 模块中的内存泄漏 - 2

    作为我的Rails应用程序的一部分,我编写了一个小导入程序,它从我们的LDAP系统中吸取数据并将其塞入一个用户表中。不幸的是,与LDAP相关的代码在遍历我们的32K用户时泄漏了大量内存,我一直无法弄清楚如何解决这个问题。这个问题似乎在某种程度上与LDAP库有关,因为当我删除对LDAP内容的调用时,内存使用情况会很好地稳定下来。此外,不断增加的对象是Net::BER::BerIdentifiedString和Net::BER::BerIdentifiedArray,它们都是LDAP库的一部分。当我运行导入时,内存使用量最终达到超过1GB的峰值。如果问题存在,我需要找到一些方法来更正我的代

  2. ruby-on-rails - 如何从 format.xml 中删除 <hash></hash> - 2

    我有一个对象has_many应呈现为xml的子对象。这不是问题。我的问题是我创建了一个Hash包含此数据,就像解析器需要它一样。但是rails自动将整个文件包含在.........我需要摆脱type="array"和我该如何处理?我没有在文档中找到任何内容。 最佳答案 我遇到了同样的问题;这是我的XML:我在用这个:entries.to_xml将散列数据转换为XML,但这会将条目的数据包装到中所以我修改了:entries.to_xml(root:"Contacts")但这仍然将转换后的XML包装在“联系人”中,将我的XML代码修改为

  3. ruby - 如何模拟 Net::HTTP::Post? - 2

    是的,我知道最好使用webmock,但我想知道如何在RSpec中模拟此方法:defmethod_to_testurl=URI.parseurireq=Net::HTTP::Post.newurl.pathres=Net::HTTP.start(url.host,url.port)do|http|http.requestreq,foo:1endresend这是RSpec:let(:uri){'http://example.com'}specify'HTTPcall'dohttp=mock:httpNet::HTTP.stub!(:start).and_yieldhttphttp.shou

  4. ruby - Infinity 和 NaN 的类型是什么? - 2

    我可以得到Infinity和NaNn=9.0/0#=>Infinityn.class#=>Floatm=0/0.0#=>NaNm.class#=>Float但是当我想直接访问Infinity或NaN时:Infinity#=>uninitializedconstantInfinity(NameError)NaN#=>uninitializedconstantNaN(NameError)什么是Infinity和NaN?它们是对象、关键字还是其他东西? 最佳答案 您看到打印为Infinity和NaN的只是Float类的两个特殊实例的字符串

  5. ruby - 检查方法参数的类型 - 2

    我不确定传递给方法的对象的类型是否正确。我可能会将一个字符串传递给一个只能处理整数的函数。某种运行时保证怎么样?我看不到比以下更好的选择:defsomeFixNumMangler(input)raise"wrongtype:integerrequired"unlessinput.class==FixNumother_stuffend有更好的选择吗? 最佳答案 使用Kernel#Integer在使用之前转换输入的方法。当无法以任何合理的方式将输入转换为整数时,它将引发ArgumentError。defmy_method(number)

  6. java - 等价于 Java 中的 Ruby Hash - 2

    我真的很习惯使用Ruby编写以下代码:my_hash={}my_hash['test']=1Java中对应的数据结构是什么? 最佳答案 HashMapmap=newHashMap();map.put("test",1);我假设? 关于java-等价于Java中的RubyHash,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/22737685/

  7. ruby-on-rails - rspec should have_select ('cars' , :options => ['volvo' , 'saab' ] 不工作 - 2

    关闭。这个问题需要detailsorclarity.它目前不接受答案。想改进这个问题吗?通过editingthispost添加细节并澄清问题.关闭8年前。Improvethisquestion在首页我有:汽车:VolvoSaabMercedesAudistatic_pages_spec.rb中的测试代码:it"shouldhavetherightselect"dovisithome_pathit{shouldhave_select('cars',:options=>['volvo','saab','mercedes','audi'])}end响应是rspec./spec/request

  8. ruby - Ruby 有 `Pair` 数据类型吗? - 2

    有时我需要处理键/值数据。我不喜欢使用数组,因为它们在大小上没有限制(很容易不小心添加超过2个项目,而且您最终需要稍后验证大小)。此外,0和1的索引变成了魔数(MagicNumber),并且在传达含义方面做得很差(“当我说0时,我的意思是head...”)。散列也不合适,因为可能会不小心添加额外的条目。我写了下面的类来解决这个问题:classPairattr_accessor:head,:taildefinitialize(h,t)@head,@tail=h,tendend它工作得很好并且解决了问题,但我很想知道:Ruby标准库是否已经带有这样一个类? 最佳

  9. ruby-on-rails - Nokogiri:使用 XPath 搜索 <div> - 2

    我使用Nokogiri(Rubygem)css搜索寻找某些在我的html里面。看起来Nokogiri的css搜索不喜欢正则表达式。我想切换到Nokogiri的xpath搜索,因为这似乎支持搜索字符串中的正则表达式。如何在xpath搜索中实现下面提到的(伪)css搜索?require'rubygems'require'nokogiri'value=Nokogiri::HTML.parse(ABBlaCD3"HTML_END#my_blockisgivenmy_bl="1"#my_eqcorrespondstothisregexmy_eq="\/[0-9]+\/"#FIXMEThefoll

  10. ruby - 查找字符串中的内容类型(数字、日期、时间、字符串等) - 2

    我正在尝试解析一个CSV文件并使用SQL命令自动为其创建一个表。CSV中的第一行给出了列标题。但我需要推断每个列的类型。Ruby中是否有任何函数可以找到每个字段中内容的类型。例如,CSV行:"12012","Test","1233.22","12:21:22","10/10/2009"应该产生像这样的类型['integer','string','float','time','date']谢谢! 最佳答案 require'time'defto_something(str)if(num=Integer(str)rescueFloat(s

随机推荐