【转载】#324 - A Generic Class Can Have More than One Type Parameter

本文深入解析了泛型类的概念及其在实际编程中的应用,通过实例展示了如何使用具有两个类型参数的泛型类来存储不同类型的对象,并在实际场景中灵活运用。

A generic class includes one or more type parameters that will be substituted with actual types when the class is used. If the class has more than one type parameter, all parameters must be substituted when the class is used.

Here's an example of a generic class that stores two objects, each having its own type.

 1 public class ThingContainer<TThing1, TThing2>
 2 {
 3     private TThing1 thing1;
 4     private TThing2 thing2;
 5 
 6     public void SetThings(TThing1 first, TThing2 second)
 7     {
 8         thing1 = first;
 9         thing2 = second;
10     }
11 
12     public string DumpThings()
13     {
14         return string.Format("{0},{1}", thing1.ToString(),             thing2.ToString());
15     }            
16 }            

We can use this class as follows:

1 ThingContainer<string, int> cont1 = new ThingContainer<string, int>();
2 cont1.SetThings("Hemingway", 1899);
3 Console.WriteLine(cont1.DumpThings());   
4 
5 ThingContainer<Dog, DateTime> cont2 = new ThingContainer<Dog, DateTime>();
6 cont2.SetThings(new Dog("Kirby", 14), new DateTime(1998, 5, 1));
7 Console.WriteLine(cont2.DumpThings());  

 原文地址:#324 - A Generic Class Can Have More than One Type Parameter

转载于:https://www.cnblogs.com/yuthreestone/p/3593561.html

=begin common class for parsing switches in ruby =end class SwitchObj attr_reader :type, :default_value, :code_block, :comment def initialize(type, variable, default_value, code_block, comment, args) @variable = variable @type = type @default_value = default_value @code_block = code_block @comment = comment @args = args @required = args[:required] @set = false end def usage if type == TrueClass # copy how cnsim does true false plusargs if @default_value string = “(-#{@variable})/-no_#{@variable} " else string = “-#{@variable}/(-no_#{@variable})” end else string = “-#{@variable} <?> default "#{@default_value}".” end string += " # #{@comment}” if @required string += " (required)"; end string += “\n” return string end # return true is switch matches this plusarg def find?(switch, value) if switch.instance_of? Symbol switch = switch.to_s end found = false #print “input #{switch} plusarg #{@variable}\n” if switch == @variable found = self end return found end # set plusarg to a new value def set!(env_obj, value) @set = true if type == Fixnum # convert param from String to Fixnum to match type if value.instance_of? String if value =~ /^0x/ value = value.hex else value = value.to_i end end elsif type == Range if value =~ /^\d+$/ # convert 10 to 10…10 value = value.to_i…value.to_i else # convert “10…30” into range value = value.split(‘…’).inject { |s,e| s.to_i…e.to_i } end end #print “found range here val is #{value} type #{value.class}\n” @code_block.call(env_obj, value) end def complain_need_to_be_set? if @required && ! @set return true end return false end end THIS IS A GENERIC PLUSARG PARSER THAT CAN BE USED ANYWHEHRE!!!############# =begin here is an example of creating switches :required => true means this switch is required :default! => “comment” all remain args become the default value. you can add a code block to parse filter things yourself class MySwitches < Switches def self.init_all_variables copy_super create_variable TrueClass, :cnsim, nil, “follows cnsim format as closely as possible”, required: true create_variable Fixnum, :insts , false, “X number of instructions per JSON obj. use this if memory footprint is large” create_variable String, :avpl, nil, “input avplist” end init_all_variables def initialize(args=Hash.new) # process default args default!(“plusargs”) do |current| if current =~ /^+/ # plusargs are okay return current else raise “unexpected plusargs #{current}” end end current + “whatever” # show you can change args super(args) end end multiple ways to set args 1. plusargs Switches(“-avplist file”) 2. hash Switches(avplist: “file”) on TrueClass (like debug) you can set and unset using the following -debug -no_debug =end class Switches attr_reader :defaults # any parameter not part of switch are aggregated here. # e.g generate_fasm … ########### CLASS METHODS ############################## # can’t put the code below in helper because I need “self” to known it is class Switches @@plusargs = Hash.new # contains a hash of hash # first level hash is the object name # second level hash is code block which sets the variable # the reason we need first level is because all Env parser inherent from # this class and we don’t want conflicts # if we don’t do this than Switches will have all the plusargs of its children @@plusargs[self.to_s] = Hash.new def self.create_variable(type, variable, default_value, comment, args=Hash.new) if ! @@plusargs[self.to_s] raise “need to run copy_super before create_variable” end if ! variable.instance_of? Symbol raise “create variable must be of Symbol. it is #{variable}, type #{variable.class}” end # make it class variable variable_string = variable.to_s variable_class = “@” + variable_string # create setter like avplist! # for getter create avplist and avplist? the “?” is better for Boolean #print “all methods #{methods.join(”,“)}\n” method_getter = (variable_string).to_sym send :define_method , method_getter do self.instance_variable_get(variable_class) end method_getter = (variable_string + “?”).to_sym send :define_method , method_getter do self.instance_variable_get(variable_class) end method_setter = (variable_string + “!”).to_sym send :define_method, method_setter do |new_value| self.instance_variable_set(variable_class, new_value) end setter_code_block = lambda do |env_obj, set_value| #print “setting:self #{env_obj.class} variable #{variable_class} value #{set_value}\n” env_obj.instance_variable_set(variable_class, set_value) #print “after avplist is #{env_obj.avplist}\n” end @@plusargs[self.to_s][variable_string] = SwitchObj.new(type, variable_string, default_value, setter_code_block, comment, args) end def self.copy_super # copy over all variables from parent class if self.superclass != Object self.superclass.copy_super @@plusargs[self.to_s] = @@plusargs[self.superclass.to_s].clone end end def initialize(args=Hash.new) # so current object has all parent class methods if ! @@plusargs[class_name] raise “need to run copy_super first” end @@plusargs[class_name].each do |variable_string, plusarg| variable_class = “@” + variable_string #print “set #{variable_class} to #{plusarg.default_value}. type #{plusarg.default_value.class}\n” self.instance_variable_set(variable_class, plusarg.default_value) end @defaults = [] @args = args parse(args) end # for instance object to access @@plusargs def class_name self.class.to_s end # everything not a plusarg becomes this def default!(comment, &block) #print “accept default is true\n” @accept_default = true @default_comment = comment if block_given? @parse_default_block = block end end def check_required_args @@plusargs[class_name].each do |name, current_plusarg| #print “check required args #{name}\n”; if current_plusarg.complain_need_to_be_set? puts “the args below is required\n#{current_plusarg.usage}” exit end end end # can parse either # String like “-avplist file” # Hash like avplist: “file” def parse(args) usage if args.empty? if args.instance_of? Array #print “arg is #{args}\n” current_plusarg = nil args.each do |current_arg| #print “current_arg is #{current_arg}\n” if current_arg =~ /^\s* / e l s i f c u r r e n t a r g = / − ( § + ) / elsifcurrent a ​ rg= / − (§+)/ # switch switch = 1 i f ( c u r r e n t a r g = / − n o ( § + ) 1 if(current a ​ rg= / − no ( ​ §+)/) || (current_arg =~ /^-no-(\S+)$/) # boolean, support both -no_blah or -no-blah version current_plusarg = find_plusarg($1, current_arg) if current_plusarg.type == TrueClass current_plusarg.set!(self, false) current_plusarg = nil # finish else raise “unexpected switch #{current_arg}. must be Boolean it is #{current_plusarg.type}” end else #print “trying to find switch #{switch}\n” current_plusarg = find_plusarg(switch, current_arg) if current_plusarg.type == TrueClass current_plusarg.set!(self, true) current_plusarg = nil # finish else current_plusarg = find_plusarg(switch, current_arg) # need to still get the value end end elsif current_plusarg # switch with parameter #print “set current_arg #{current_arg}. class #{current_arg.class}. plusarg #{current_plusarg.class}\n” current_plusarg.set!(self, current_arg) current_plusarg = nil # finish switch with parameter else # just parameter without association to plusargs #print “parsing #{current_arg} accept default is #{@accept_default}\n” if @accept_default if @parse_default_block current_arg = @parse_default_block.call(current_arg) end @defaults.push current_arg else print “unexpected input #{current_arg}\n” usage end end end elsif args.instance_of? Hash args.each do |switch, value| plusarg = find_plusargs(switch, switch) plusarg.set(self, value) end else raise “unexpected args class. arg is #{args}. type #{args.class}. must be String or Hash” end check_required_args end def find_plusarg(switch, orig_switch_string) # foreach token (which is switch, check against @plusargs) found_plusarg = false @@plusargs[class_name].each do |name, current_plusarg| found_plusarg = current_plusarg.find?(switch, orig_switch_string) break if found_plusarg end #print “afterwards avplist is #{@avplist}\n” if ! found_plusarg print “can’t find switch #{orig_switch_string}\n” usage end return found_plusarg end def usage string = “” @@plusargs[class_name].each do |name, current_plusarg| string += current_plusarg.usage end if @accept_default string += “ … ##{@default_comment}\n” end print “#{$0}\n” print string exit end # dump the original args for debug def to_s string = “” if @rng string += “seed: #{@rng.seed}\n” end string += "switch: " + @args.to_s end end 麻烦你为我详细解析这段代码,需要逐行解析,且我不太懂ruby语法因此除了代码解析你还需要顺便给我讲讲语法
10-28
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值