国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

C#模擬C++模板特化對類型的值的支持

這篇具有很好參考價值的文章主要介紹了C#模擬C++模板特化對類型的值的支持。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

概述

C++的模板相比于C#的泛型,有很多地方都更加的靈活(雖然代價是降低了編譯速度),比如C++支持變長參數(shù)模板、支持枚舉、int等類型的值作為模板參數(shù)。
C++支持枚舉、int等類型的值作為模板參數(shù),為C++的靜態(tài)多態(tài)編程提供了很好的幫助,比如根據(jù)枚舉值編譯期確定某個對象的行為策略等(下文舉例)。但是C#對這些都是不支持,但是C#天然支持反射,這種需求可以使用反射特性來實現(xiàn)。

需求示例

定義枚舉 enum EPlant {Tree, Flower},根據(jù)枚舉的值打印Tree,Flower字符串。注意,這里的應(yīng)用場景是編譯器時的多態(tài),即編碼時便確定使用的對象的類型。

C++的實現(xiàn)

上述的例子,C++的語法支持可以天然的實現(xiàn),如下:

#include <iostream>

enum class EPlant
{
    Tree = 0,
    Flower,
};

template<EPlant ...Args>
class PrintPlant
{
    
};

template<>
class PrintPlant<>
{
public:
    void Print()
    {
        std::cout << "Plant" << std::endl;;
    }
};

template<>
class PrintPlant<EPlant::Tree>
{
public: 
    void Print()
    {
        std::cout << "Tree" << std::endl;;
    }
};

template<>
class PrintPlant<EPlant::Flower>
{
public:
    void Print()
    {
        std::cout << "Flower" << std::endl;
    }
};

int main()
{
    auto plant = new PrintPlant<>();
    plant->Print();
    auto flower = new PrintPlant<EPlant::Flower>();
    flower->Print();
    auto tree = new PrintPlant<EPlant::Tree>();
    tree->Print();
}

輸出:
C#模擬C++模板特化對類型的值的支持

  • template<EPlant ...Args> 這里使用變長參數(shù)模板,來支持沒有傳入模板參數(shù)的情況,特化類型Print函數(shù)打印"plant"
  • template<> class PrintPlant<EPlant::Tree> 模板特化的類型,在main里使用了new PrintPlant<EPlant::Tree>();語句創(chuàng)建該類型的對象。該對象打印"Tree"。

C# 實現(xiàn)

C#的模板不支持枚舉的值作為模板參數(shù),使用反射進行模擬。

using System;
using System.Reflection;
using System.Collections.Generic;

[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
public class ABTEX : Attribute
{
    public object key;

    public ABTEX(object k)
    {
        key = k;
    }
}

public class TEX
{
    static Dictionary<Type, Dictionary<Type, Dictionary<string, object>>> dict;
    public static void Init(Type[] types)
    {
        dict = new();
        foreach (var t in types)
        {
            var ABTEX = t.GetCustomAttribute<ABTEX>();
            var bt = t.BaseType;
            if (ABTEX != null && bt != null)
            {
                AddInst(t, bt, ABTEX.key);
            }
        }
    }

    static string FmtKey(object key)
    {
        return $"{key}";
    }

    static void AddInst(Type ty, Type bt, object key)
    {
        if (!dict.ContainsKey(bt))
        {
            dict[bt] = new();
        }

        var kt = key.GetType();
        string k = FmtKey(key);

        if (!dict[bt].ContainsKey(kt))
        {
            dict[bt][kt] = new();
        }

        dict[bt][kt][k] = Activator.CreateInstance(ty);
    }

    static public R T<R>(object key)
    {
        if (dict.TryGetValue(typeof(R), out Dictionary<Type, Dictionary<string, object>> dbt))
        {
            var kt = key.GetType();
            string k = FmtKey(key);
            if (dbt.TryGetValue(kt, out Dictionary<string, object> kbt))
            {
                if (kbt.TryGetValue(k, out object ins))
                {
                    return (R)ins;
                }
            }
        }

        return default(R);
    }
}

public enum EPlant : int
{
    None = 0,
    Tree,
    Flower,
}

public class APrintPlant
{
    public virtual void Print()
    {
        Console.WriteLine("Plant");
    }
}

[ABTEX(EPlant.Tree)]
public class PrintTree : APrintPlant
{
    public override void Print()
    {
        Console.WriteLine("Tree");
    }
}

[ABTEX(EPlant.Flower)]
public class PrintFlower : APrintPlant
{
    public override void Print()
    {
        Console.WriteLine("Flower");
    }
}

class Program
{
    static void Main(string[] args)
    {
        var all = Assembly.GetExecutingAssembly().GetTypes();
        TEX.Init(all);
        TEX.T<APrintPlant>(EPlant.Tree).Print();
        TEX.T<APrintPlant>(EPlant.Flower).Print();
    }
}

輸出:
C#模擬C++模板特化對類型的值的支持
C#可以保存類型信息到運行期,通過運行期分析類型信息創(chuàng)建對象實現(xiàn)靜態(tài)多態(tài)。文章來源地址http://www.zghlxwxcb.cn/news/detail-416457.html

  • TEX類分析傳入的所有類型,篩選父類和ABTEX特性,使用父類型,ABTEX的key的類型和值來索引該類型。(這里索引是實例對象,有需求的話可以保存類型Type,使用類型通過反射創(chuàng)建對象)
  • ABTEX標(biāo)記需要反射分析的類型,并且標(biāo)記key。
  • Main入口獲取當(dāng)前程序集下所有的類型信息,初始化TEX
  • 通過TEX.T<抽象類>(key).Func 調(diào)用方法(注意: 這里使用這些類作為純函數(shù)的類,故使用類似單例的用法。也可以在初始化記錄類型,通過反射創(chuàng)建多個實例。)

到了這里,關(guān)于C#模擬C++模板特化對類型的值的支持的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

  • 【C++學(xué)習(xí)】模板進階——非類型模板參數(shù) | 模板的特化 | 分離編譯

    【C++學(xué)習(xí)】模板進階——非類型模板參數(shù) | 模板的特化 | 分離編譯

    ??作者:一只大喵咪1201 ??專欄:《C++學(xué)習(xí)》 ??格言: 你只管努力,剩下的交給時間! 模板我們之前一直都在使用,尤其是在模擬STL容器的時候,可以說,模板給類增加了更多的可能性,是C++最重要的部分之一。下面本喵來更深入的講解一下模板。 在上面代碼中,創(chuàng)建了

    2023年04月13日
    瀏覽(21)
  • 【C++】模板進階—非類型模板參數(shù)、模板特化及模板的分離編譯

    【C++】模板進階—非類型模板參數(shù)、模板特化及模板的分離編譯

    ?? 作者簡介:一名在后端領(lǐng)域?qū)W習(xí),并渴望能夠?qū)W有所成的追夢人。 ?? 個人主頁:不 良 ?? 系列專欄:??C++ ???Linux ?? 學(xué)習(xí)格言:博觀而約取,厚積而薄發(fā) ?? 歡迎進來的小伙伴,如果小伙伴們在學(xué)習(xí)的過程中,發(fā)現(xiàn)有需要糾正的地方,煩請指正,希望能夠與諸君一同

    2024年02月16日
    瀏覽(23)
  • 【C++初階(十)】C++模板(進階) ---非類型模板參數(shù)、模板的特化以及模板的分離編譯

    【C++初階(十)】C++模板(進階) ---非類型模板參數(shù)、模板的特化以及模板的分離編譯

    本專欄內(nèi)容為:C++學(xué)習(xí)專欄,分為初階和進階兩部分。 通過本專欄的深入學(xué)習(xí),你可以了解并掌握C++。 ??博主csdn個人主頁:小小unicorn ?專欄分類:C++ ??代碼倉庫:小小unicorn的代碼倉庫?? ??????關(guān)注我?guī)銓W(xué)習(xí)編程知識 模板參數(shù)可分為類型形參和非類型形參。 類型形

    2024年01月18日
    瀏覽(18)
  • 【C++】模板+模板特化

    【C++】模板+模板特化

    鐵汁們,今天給大家分享一篇模板+模板特化,來吧,開造?? 定義:編寫跟具體類型無關(guān)的通用代碼,是實現(xiàn)代碼復(fù)用的一種手段。模板是泛型編程的基礎(chǔ)。 問:如何實現(xiàn)一個通用的swap函數(shù)? 答:寫成函數(shù)模板,不能在函數(shù)重載了。原因:代碼復(fù)用率低,重載的函數(shù)僅是

    2024年03月24日
    瀏覽(21)
  • C++類模板的特化(三)

    本文主要介紹類模板的特化、局部特化和缺省模板實參; 類模板的特化(Class Template Specialization)是指為特定的模板參數(shù)提供自定義實現(xiàn)的過程。通過特化,我們可以針對某些特定的類型或條件提供不同的行為或?qū)崿F(xiàn); 如果需要特化一個類模板,需要特化該模板中的所有成員

    2024年02月11日
    瀏覽(17)
  • C++標(biāo)準模板(STL)- 類型支持 (數(shù)值極限,C 數(shù)值極限接口)

    參閱 std::numeric_limits 接口 定義于頭文件 cstdint PTRDIFF_MIN (C++11) std::ptrdiff_t 類型對象的最小值 (宏常量) PTRDIFF_MAX (C++11) std::ptrdiff_t 類型對象的最大值 (宏常量) SIZE_MAX (C++11) std::size_t 類型對象的最大值 (宏常量) SIG_ATOMIC_MIN (C++11) std::sig_atomic_t 類型對象的最小值 (宏常量) SIG_ATOMIC_

    2024年02月07日
    瀏覽(18)
  • C#的值類型和引用類型

    在C#中,數(shù)據(jù)類型可以分為值類型(Value Types)和引用類型(Reference Types)兩種。下面是對它們的詳細解釋和示例說明: 值類型(Value Types): 值類型變量直接包含它們的數(shù)據(jù),存儲在棧上。 值類型包括整數(shù)類型(如int、byte、char)、浮點類型(如float、double)、布爾類型(如

    2024年02月15日
    瀏覽(21)
  • C++標(biāo)準模板(STL)- 類型支持 (類型特性,is_union,is_class,is_function)

    C++標(biāo)準模板(STL)- 類型支持 (類型特性,is_union,is_class,is_function)

    類型特性定義一個編譯時基于模板的結(jié)構(gòu),以查詢或修改類型的屬性。 試圖特化定義于 type_traits 頭文件的模板導(dǎo)致未定義行為,除了 std::common_type 可依照其所描述特化。 定義于type_traits頭文件的模板可以用不完整類型實例化,除非另外有指定,盡管通常禁止以不完整類型實

    2024年02月06日
    瀏覽(27)
  • 重溫C#中的值類型和引用類型

    在C#中,數(shù)據(jù)類型分為 值類型 和 引用類型 兩種。 引用類型變量存儲的是數(shù)據(jù)的引用,數(shù)據(jù)存儲在數(shù)據(jù)堆中,而值類型變量直接存儲數(shù)據(jù)。對于引用類型,兩個變量可以引用同一個對象。因此,對一個變量的操作可能會影響另一個變量引用的對象。對于值類型,每個變量都有

    2024年02月15日
    瀏覽(23)
  • C++標(biāo)準模板(STL)- 類型支持 (類型特性,is_member_object_pointer,is_member_function_pointer)

    C++標(biāo)準模板(STL)- 類型支持 (類型特性,is_member_object_pointer,is_member_function_pointer)

    類型特性定義一個編譯時基于模板的結(jié)構(gòu),以查詢或修改類型的屬性。 試圖特化定義于 type_traits 頭文件的模板導(dǎo)致未定義行為,除了 std::common_type 可依照其所描述特化。 定義于type_traits頭文件的模板可以用不完整類型實例化,除非另外有指定,盡管通常禁止以不完整類型實

    2024年02月08日
    瀏覽(29)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包