CA2202, কীভাবে এই মামলা সমাধান করবেন


102

কেউ আমাকে কীভাবে নীচের কোড থেকে সমস্ত CA2202 সতর্কতাগুলি সরিয়ে ফেলতে পারেন?

public static byte[] Encrypt(string data, byte[] key, byte[] iv)
{
    using(MemoryStream memoryStream = new MemoryStream())
    {
        using (DESCryptoServiceProvider cryptograph = new DESCryptoServiceProvider())
        {
            using (CryptoStream cryptoStream = new CryptoStream(memoryStream, cryptograph.CreateEncryptor(key, iv), CryptoStreamMode.Write))
            {
                using(StreamWriter streamWriter = new StreamWriter(cryptoStream))
                {
                    streamWriter.Write(data);
                }
            }
        }
        return memoryStream.ToArray();
    }
}

সতর্কতা 7 CA2202: মাইক্রোসফ্ট। ব্যবহার: অবজেক্ট 'ক্রিপ্টোস্ট্রিম' পদ্ধতিতে একাধিকবার নিষ্পত্তি করা যেতে পারে 'ক্রিপ্টো সার্ভিসেস। এনক্রিপ্ট (স্ট্রিং, বাইট [], বাইট [])'। একটি সিস্টেম তৈরি করা এড়ানোর জন্য। অবজেক্ট ডিসপোজড এক্সসেপশন আপনাকে কোনও বস্তুর উপর একাধিকবার ডিসপোজ কল করতে হবে না: লাইন: 34

সতর্কতা 8 সিএ 2202: মাইক্রোসফ্ট.উপস: অবজেক্ট 'মেমরিস্ট্রিম' পদ্ধতিতে একাধিকবার নিষ্পত্তি করা যেতে পারে 'ক্রিপ্টো সার্ভিসেস। এনক্রিপ্ট (স্ট্রিং, বাইট [], বাইট [])'। একটি সিস্টেম তৈরি করা এড়ানোর জন্য। অবজেক্ট ডিসপোজড এক্সসেপশন আপনাকে কোনও বস্তুর উপর একাধিকবার ডিসপোজ কল করতে হবে না: লাইন: 34, 37

এই সতর্কতাগুলি দেখতে আপনার ভিজ্যুয়াল স্টুডিও কোড বিশ্লেষণ প্রয়োজন (এগুলি সি # সংকলক সতর্কতা নয়)।


1
এই কোডটি এই সতর্কতাগুলি উত্পন্ন করে না।
জুলিয়ান হোয়ারাউ

1
আমি এর জন্য 0 টি সতর্কতা পেয়েছি (সতর্কতা স্তর 4, ভিএস 2010)। এবং এই ক্ষেত্রে কারও কারও পক্ষে গুগল করার সমস্যা, অনুরোধটি সতর্কতার পাঠ্যও যুক্ত করুন।
হেন্ক হলটারম্যান

29
কোড অ্যানালাইসিস এবং এফএক্সকপ দ্বারা সিএএক্সএক্সএক্সএক্সএক্সএক্স সতর্কতা উত্পন্ন হয় ।
ডিটিবি

এই সতর্কতাটি দেখানো কোডে প্রযোজ্য নয় - সতর্কতাগুলি এই দৃশ্যের জন্য দমন করা যায়। আপনি একবার আপনার কোড পর্যালোচনা করে নিয়েছেন এবং সেই মূল্যায়নের সাথে একমত হয়ে গেলে, আপনার পদ্ধতির উপরে এটি রাখুন: " [SuppressMessage("Microsoft.Usage", "CA2202:Do not dispose objects multiple times", Justification="BrainSlugs83 said so.")]" - using System.Diagnostics.CodeAnalysis;আপনার ইউএসিং ব্লকে আপনার " " বিবৃতি রয়েছে কিনা তা নিশ্চিত হয়ে নিন।
BrainSlugs83

উত্তর:


-3

এই সতর্কতা ছাড়াই সংকলন:

    public static byte[] Encrypt(string data, byte[] key, byte[] iv)
    {
        MemoryStream memoryStream = null;
        DESCryptoServiceProvider cryptograph = null;
        CryptoStream cryptoStream = null;
        StreamWriter streamWriter = null;
        try
        {
            memoryStream = new MemoryStream();
            cryptograph = new DESCryptoServiceProvider();
            cryptoStream = new CryptoStream(memoryStream, cryptograph.CreateEncryptor(key, iv), CryptoStreamMode.Write);
            var result = memoryStream;              
            memoryStream = null;
            streamWriter = new StreamWriter(cryptoStream);
            cryptoStream = null;
            streamWriter.Write(data);
            return result.ToArray();
        }
        finally
        {
            if (memoryStream != null)
                memoryStream.Dispose();
            if (cryptograph != null)
                cryptograph.Dispose();
            if (cryptoStream != null)
                cryptoStream.Dispose();
            if (streamWriter != null)
                streamWriter.Dispose();
        }
    }

মন্তব্যের জবাবে সম্পাদনা করুন : আমি আবারও যাচাই করেছি যে এই কোডটি সতর্কতা তৈরি করে না, যখন মূলটি তা করে। মূল কোডে CryptoStream.Dispose()এবং MemoryStream().Dispose() আসলে দুটিবার বলা হয় (যা সমস্যা হতে পারে বা নাও পারে)।

পরিবর্তিত কোড নিম্নরূপে কাজ করে: nullনিষ্পত্তি করার জন্য দায়বদ্ধতার সাথে সাথে অন্য কোনও বস্তুতে স্থানান্তরিত হওয়ার সাথে সাথে রেফারেন্সগুলি সেট করা হয়। যেমন memoryStreamসেট করা হয় nullপর থেকে কল CryptoStreamকন্সট্রাকটর সফল হয়েছে। কনস্ট্রাক্টরের কল সফল হওয়ার পরে cryptoStreamসেট করা আছে । যদি কোনও ব্যতিক্রম ঘটে না, তবে ব্লকে তা নিষ্পত্তি করা হবে এবং পরিবর্তে তা নিষ্পত্তি হবে এবং ।nullStreamWriterstreamWriterfinallyCryptoStreamMemoryStream


85
-1 দমন করা উচিত এমন একটি সতর্কতা মেনে চলার জন্য কুৎসিত কোড তৈরি করা সত্যিই খারাপ ।
জর্দো

4
আমি সম্মত হলাম যে আপনি এমন কোনও কিছুর কোড কইবেন না যা ভবিষ্যতে কোনও সময়ে স্থির হয়ে যেতে পারে, কেবল দমন করুন।
পেটেস্কি

3
এটি কীভাবে সমস্যার সমাধান করবে? CA2202 এখনও অবহিত করা হয়েছে কারণ মেমরিস্ট্রিমটি এখনও অবশেষে ব্লকের মধ্যে দুবার নিষ্পত্তি হতে পারে।
ক্রিস গেসলার

3
যেহেতু ক্রিপ্টোস্ট্রিম মেমরিস্ট্রিমটিকে অভ্যন্তরীণভাবে ডিসপোজ কল করে তাই এটি দুটিবার বলা যেতে পারে যা সতর্কতার কারণ। আমি আপনার সমাধান চেষ্টা করেছিলাম এবং এখনও সতর্কতা পেয়েছি।
ক্রিস গেসলার

2
ওহে জিজ, আপনি সঠিক - আমি আশা করি না যে সেখানে আপনার ... যুক্তি-যুক্তি ... - এটি কেবল উদ্ভট এবং রহস্যজনক - এটি অবশ্যই চতুর - তবে আবার, ভীতিজনক - দয়া করে উত্পাদন কোডে এটি করবেন না; পরিষ্কার হতে হবে: আপনি বুঝতে পারেন যে কোনও আসল কার্যকরী সমস্যা নেই যা এটি সমাধান করছে, সঠিক? (এই বিষয়গুলি একাধিক বার নিষ্পত্তি করা ঠিক আছে)) - আমি পারলে ডাউন ভোটটি সরিয়ে ফেলতাম (এসও আমাকে বাধা দেয়, এটি আপনাকে উত্তরটি সম্পাদন করতে হবে) - তবে আমি কেবল অনিচ্ছায় তাই করব ... - এবং গুরুত্ব সহকারে, কখনও এটি করবেন না।
BrainSlugs83

142

এই ক্ষেত্রে আপনার সতর্কতাগুলি দমন করা উচিত। ডিসপোজেবলের সাথে ডিল করা কোডটি সামঞ্জস্যপূর্ণ হওয়া উচিত এবং আপনার অন্যান্য যত্নের যত্ন নেওয়া উচিত নয় যে অন্যান্য ক্লাসগুলি আপনার তৈরি ডিসপোজেবলগুলির মালিকানা গ্রহণ করবে এবং সেগুলিতেও আহ্বান জানাবে Dispose

[SuppressMessage("Microsoft.Usage", "CA2202:Do not dispose objects multiple times")]
public static byte[] Encrypt(string data, byte[] key, byte[] iv) {
  using (var memoryStream = new MemoryStream()) {
    using (var cryptograph = new DESCryptoServiceProvider())
    using (var cryptoStream = new CryptoStream(memoryStream, cryptograph.CreateEncryptor(key, iv), CryptoStreamMode.Write))
    using (var streamWriter = new StreamWriter(cryptoStream)) {
      streamWriter.Write(data);
    }
    return memoryStream.ToArray();
  }
}

আপডেট: ইন IDisposable.Dispose ডকুমেন্টেশন আপনি এটা পড়তে পারেন:

যদি কোনও বস্তুর ডিসপোজ পদ্ধতিটি একাধিকবার কল করা হয় তবে অবজেক্টটিকে অবশ্যই প্রথম কলটির পরে সমস্ত কল উপেক্ষা করতে হবে। যদি ডিসপোজ পদ্ধতিটিকে একাধিকবার বলা হয় তবে অবজেক্টটি অবশ্যই একটি ব্যতিক্রম ছুঁড়ে না ফেলে।

এটি যুক্তিযুক্ত হতে পারে যে এই নিয়মটি বিদ্যমান তাই বিকাশকারীরা usingবিবৃতিটি ডিসপোজেবলের ক্যাসকেডে সান্নিধ্যে কাজে লাগাতে পারে , যেমন আমি উপরে দেখিয়েছি (বা এটি সম্ভবত একটি দুর্দান্ত পার্শ্ব-প্রতিক্রিয়া)। একই টোকেন দ্বারা, তবে, CA2202 কোনও কার্যকর উদ্দেশ্যে কাজ করে না এবং এটি প্রকল্প-ভিত্তিতে দমন করা উচিত। আসল অপরাধী হ'ল ত্রুটিযুক্ত বাস্তবায়ন হবে Disposeএবং CA1065 এর যত্ন নেওয়া উচিত (এটি যদি আপনার দায়িত্বে থাকে)।


14
আমার মতে এটি fxcop এ একটি বাগ, এই নিয়মটি কেবল ভুল। নিষ্পত্তি পদ্ধতিটি কখনই কোনও অবজেক্ট ডিসপোজড এক্সেপশন নিক্ষেপ করা উচিত নয় এবং যদি তা হয়ে থাকে তবে আপনাকে সেই সময় কোডটির লেখককে এইভাবে নিষ্পত্তি করার জন্য কোনও বাগ ফাইল করে এটি মোকাবেলা করা উচিত।
justin.m.chase

14
আমি অন্যান্য থ্রেডে @ হান্সপাস্যান্টের সাথে একমত: এই সরঞ্জামটি তার কাজ করছে এবং ক্লাসগুলির একটি অপ্রত্যাশিত বাস্তবায়নের বিশদ সম্পর্কে আপনাকে সতর্ক করে দিচ্ছে। ব্যক্তিগতভাবে, আমি মনে করি আসল সমস্যাটি হ'ল এপিআইগুলির নিজস্ব নকশা। নেস্টেড ক্লাসগুলি অন্যথায় তৈরি অন্য কোনও সামগ্রীর মালিকানা গ্রহণ করা ঠিক আছে কিনা তা অনুমান করার জন্য এটি খুব সন্দেহজনক বলে মনে হয়। আমি দেখতে পাচ্ছি যে ফলস্বরূপ অবজেক্টটি ফেরত দেওয়া হলে এটি কোথায় কার্যকর হতে পারে, তবে সেই অনুমানের কাছে ডিফল্ট করা স্বতঃস্ফূর্ত মনে হয়, পাশাপাশি সাধারণ আইডেস্পোজেবল নিদর্শন লঙ্ঘন করে।
বিটিজে

8
কিন্তু এমএসডিএন এই ধরণের বার্তাকে সুপারিশ করতে পুনরায় প্রস্তাব দেয় না। এক নজরে
আদিল মামাডভ

2
@ অ্যাডিলম্যামাদভ লিঙ্কের জন্য ধন্যবাদ, দরকারী তথ্য তবে মাইক্রোসফ্ট এই বিষয়গুলি সম্পর্কে সর্বদা সঠিক নয়।
টিম আবেল

40

ঠিক আছে, এটি সঠিক, এই স্ট্রিমগুলিতে ডিসপোজ () পদ্ধতিটি একাধিকবার বলা হবে। স্ট্রিমরিডার শ্রেণি ক্রিপ্টোস্ট্রিমের 'মালিকানা' নেবে তাই স্ট্রিমরাইটার নিষ্পত্তি করার সাথে সাথে ক্রিপ্টোস্ট্রিমও নিষ্পত্তি করবে। একইভাবে, ক্রিপ্টোস্ট্রিম ক্লাস মেমরির স্ট্রিমের জন্য দায়িত্ব গ্রহণ করে।

এগুলি হ'ল বাস্তব বাগ নয়, এই। নেট ক্লাসগুলি একাধিক ডিসপোজ () কলগুলিতে মনোযোগী হয়। তবে আপনি যদি সতর্কতা থেকে মুক্তি পেতে চান তবে এই বিষয়গুলির জন্য আপনার ব্যবহারের বিবৃতিটি ড্রপ করা উচিত। কোডটি যদি ব্যতিক্রম ছুঁড়ে দেয় তবে কী হবে তা যুক্তি করার সময় নিজেকে কিছুটা ব্যথা করুন। বা কোনও বৈশিষ্ট্য সহ সতর্কতাটি বন্ধ করে দিন। বা কেবল সতর্কতা অবহেলা করুন কারণ এটি নির্বোধ।


10
শ্রেণীর অভ্যন্তরীণ আচরণ সম্পর্কে বিশেষ জ্ঞান থাকা (অন্যটির মালিকানা গ্রহণযোগ্যতার মতো) কেউ যদি পুনরায় ব্যবহারযোগ্য এপিআই ডিজাইন করতে চায় কিনা তা জিজ্ঞাসা করা খুব বেশি। সুতরাং আমি মনে করি যে usingবিবৃতিগুলি থাকা উচিত। এই সতর্কতা সত্যিই নির্বোধ।
জর্দো

4
@ জর্দো - হাতিয়ার কী তা নয়? অভ্যন্তরীণ আচরণ সম্পর্কে আপনাকে সতর্ক করতে আপনি হয়ত জানেন না?
হান্স প্যাস্যান্ট

8
আমি রাজী. তবে, আমি এখনও usingবিবৃতি ছেড়ে দেব না । আমি তৈরি করেছি এমন একটি বস্তুর নিষ্পত্তি করতে অন্য কোনও বস্তুর উপর নির্ভর করা কেবল ভুল অনুভব করে। এই কোডের জন্য, এটি ঠিক আছে, তবে এর অনেকগুলি বাস্তবায়ন রয়েছে Streamএবং TextWriterসেখানে (কেবলমাত্র ছাত্রলীগেই নয়)। তাদের সমস্ত ব্যবহারের কোডটি সামঞ্জস্যপূর্ণ হওয়া উচিত।
জর্দো

3
হ্যাঁ, জর্ডোওয়ের সাথে একমত আপনি যদি সত্যই চান প্রোগ্রামারটি এপিআই-এর অভ্যন্তরীণ আচরণ সম্পর্কে সচেতন, তবে আপনার ফাংশনটিকে ডসোমিংথিংএন্ডডিসপোজ স্ট্রিম (স্ট্রিম স্ট্রিম, অন্যান্য ডেটা ডেটা) হিসাবে নামকরণ করে কথা বলুন।
ZZZ

4
@ હંসপাস্যান্ট আপনি কী এটি নির্দেশ করতে পারেন যেখানে এটি নথিবদ্ধ করা হয়েছে যে XmlDocument.Save()পদ্ধতিটি Disposeসরবরাহিত প্যারামিটারে কল করবে ? আমি এটি ডকুমেন্টেশনে Save(XmlWriter)(যেখানে আমি FxCop বাগটি অনুভব করছি), বা Save()পদ্ধতিতে বা নিজেই নথিতে দেখছি না XmlDocument
আয়ান

9

যখন একটি স্ট্রাইমাইটার নিষ্পত্তি হয়, এটি স্বয়ংক্রিয়ভাবে মোড়ানো স্ট্রিমটি নিষ্পত্তি করে (এখানে: ক্রিপ্টোস্ট্রিম )। CryptoStream স্বয়ংক্রিয়ভাবে আবৃত মীমাংসা করে স্ট্রিম (: এখান MemoryStream )।

সুতরাং আপনার MemoryStream দ্বারা উভয় বিন্যস্ত করা হয় CryptoStream এবং ব্যবহার বিবৃতি। এবং আপনার ক্রিপ্টোস্ট্রিম স্ট্রিমাইটার এবং বাইরের ব্যবহারের বিবৃতি দ্বারা নিষ্পত্তি করা হয়েছে।


কিছু পরীক্ষা-নিরীক্ষার পরে সতর্কতা থেকে সম্পূর্ণ মুক্তি পাওয়া অসম্ভব বলে মনে হচ্ছে। তাত্ত্বিকভাবে, মেমরিস্ট্রিমটি নিষ্পত্তি করা দরকার তবে আপনি তাত্ত্বিকভাবে আর এর ToArray পদ্ধতিতে অ্যাক্সেস করতে পারেন নি। কার্যত, একটি মেমরিস্ট্রিম নিষ্পত্তি করার প্রয়োজন হয় না, তাই আমি এই সমাধানটি নিয়ে গিয়ে CA2000 সতর্কতাটি দমন করব।

var memoryStream = new MemoryStream();

using (var cryptograph = new DESCryptoServiceProvider())
using (var writer = new StreamWriter(new CryptoStream(memoryStream, ...)))
{
    writer.Write(data);
}

return memoryStream.ToArray();

9

আমি এটি ব্যবহার করে করব #pragma warning disable

.NET ফ্রেমওয়ার্ক গাইডলাইনগুলি IDisposable প্রয়োগ করার জন্য সুপারিশ করে is এমনভাবে আলোচনা করুন যাতে এটি একাধিকবার বলা যেতে পারে। IDisposable.Dispose এর MSDN বর্ণনা থেকে :

যদি ডিসপোজ পদ্ধতিটিকে একাধিকবার বলা হয় তবে অবজেক্টটিকে অবশ্যই একটি ব্যতিক্রম ছুঁড়ে ফেলা উচিত নয়

সুতরাং সতর্কতাটি প্রায় অর্থহীন বলে মনে হচ্ছে:

সিস্টেম তৈরি করা এড়ানোর জন্য। অবজেক্ট ডিসপোজড এক্সসেপশন আপনাকে কোনও বস্তুতে ডিসপোজকে একাধিকবার কল করা উচিত নয়

আমার ধারণা, এটি যুক্তিযুক্ত হতে পারে যে সতর্কতা কার্যকর হতে পারে যদি আপনি কোনও কার্যকরভাবে প্রয়োগ করা আইডিস্পোজেবল অবজেক্ট ব্যবহার করেন যা মানক বাস্তবায়ন নির্দেশিকা অনুসরণ করে না। তবে আপনার মতো। নেট ফ্রেমওয়ার্ক থেকে ক্লাস ব্যবহার করার সময়, আমি বলব যে # প্রগমা ব্যবহার করে সতর্কতা দমন করা নিরাপদ। এবং এই সতর্কতার জন্য এমএসডিএন ডকুমেন্টেশনে প্রস্তাবিত আইএমএইচও এটি হুপগুলির মধ্য দিয়ে যাওয়া ভাল ।


4
CA2202 একটি কোড বিশ্লেষণ সতর্কতা এবং সংকলক সতর্কতা নয়। #pragma warning disableকেবল সংকলক সতর্কতা দমন করতে ব্যবহার করা যেতে পারে। কোড বিশ্লেষণ সতর্কতা দমন করতে আপনার একটি গুণাবলী ব্যবহার করা দরকার।
মার্টিন লিভারেজ

2

আমার কোডে আমি একই ধরণের সমস্যার মুখোমুখি হয়েছিলাম।

দেখে মনে হচ্ছে পুরো CA2202 জিনিসটি ট্রিগার হয়েছে কারণ MemoryStreamকনস্ট্রাক্টর (CA2000) এ ব্যতিক্রম দেখা দিলে তা নিষ্পত্তি করা যেতে পারে।

এটি এর মতো সমাধান হতে পারে:

 1 public static byte[] Encrypt(string data, byte[] key, byte[] iv)
 2 {
 3    MemoryStream memoryStream = GetMemoryStream();
 4    using (DESCryptoServiceProvider cryptograph = new DESCryptoServiceProvider())
 5    {
 6        CryptoStream cryptoStream = new CryptoStream(memoryStream, cryptograph.CreateEncryptor(key, iv), CryptoStreamMode.Write);
 7        using (StreamWriter streamWriter = new StreamWriter(cryptoStream))
 8        {
 9            streamWriter.Write(data);
10            return memoryStream.ToArray();
11        }
12    }
13 }
14
15 /// <summary>
16 /// Gets the memory stream.
17 /// </summary>
18 /// <returns>A new memory stream</returns>
19 private static MemoryStream GetMemoryStream()
20 {
21     MemoryStream stream;
22     MemoryStream tempStream = null;
23     try
24     {
25         tempStream = new MemoryStream();
26
27         stream = tempStream;
28         tempStream = null;
29     }
30     finally
31     {
32         if (tempStream != null)
33             tempStream.Dispose();
34     }
35     return stream;
36 }

লক্ষ্য করুন যে আমাদের memoryStreamশেষ usingস্টেটমেন্টের ভিতরে (লাইন 10) ফিরিয়ে আনতে cryptoStreamহবে কারণ এটি লাইন 11-এ নিষ্পত্তি হয়েছে (কারণ এটি streamWriter usingবিবৃতিতে ব্যবহৃত হয়েছে ), যা memoryStreamলাইন 11-এও নিষ্পত্তি হয়ে যায় (কারণ memoryStreamএটি তৈরিতে ব্যবহৃত হয় cryptoStream)।

কমপক্ষে এই কোডটি আমার পক্ষে কাজ করেছিল।

সম্পাদনা করুন:

মজাদার শোনার মতো, আমি আবিষ্কার করেছি যে আপনি যদি এই GetMemoryStreamপদ্ধতিটি নিম্নলিখিত কোড দিয়ে প্রতিস্থাপন করেন ,

/// <summary>
/// Gets a memory stream.
/// </summary>
/// <returns>A new memory stream</returns>
private static MemoryStream GetMemoryStream()
{
    return new MemoryStream();
}

আপনি একই ফলাফল পেতে।


1

ক্রিপ্টোস্ট্রিম স্মৃতিধারার উপর ভিত্তি করে।

যা ঘটতে দেখা যাচ্ছে তা হ'ল যখন ক্রিপোস্ট্রিমে নিষ্পত্তি হয় (ব্যবহার শেষে) স্মৃতিপ্রবাহটিও নিষ্পত্তি হয়, তখন স্মৃতি প্রবাহটি আবার নিষ্পত্তি হয়।


1

আমি এটি সঠিক উপায়ে সমাধান করতে চেয়েছিলাম - এটি হুঁশিয়ারিগুলিকে দমন না করে এবং সমস্ত নিষ্পত্তিযোগ্য বস্তুগুলি যথাযথভাবে নিষ্পত্তি করা ছাড়া।

আমি ক্ষেত্র হিসাবে 3 টির মধ্যে 2 টি স্ট্রিম টেনে এনেছি এবং Dispose()আমার ক্লাসের পদ্ধতিতে সেগুলি নিষ্পত্তি করেছি । হ্যাঁ, IDisposableইন্টারফেসটি বাস্তবায়ন করা আপনি অগত্যা যা খুঁজছেন তা হতে পারে না dispose()তবে কোডের সমস্ত এলোমেলো স্থানগুলির কলগুলির তুলনায় সমাধানটি বেশ পরিষ্কার দেখাচ্ছে ।

public class SomeEncryption : IDisposable
    {
        private MemoryStream memoryStream;

        private CryptoStream cryptoStream;

        public static byte[] Encrypt(string data, byte[] key, byte[] iv)
        {
             // Do something
             this.memoryStream = new MemoryStream();
             this.cryptoStream = new CryptoStream(this.memoryStream, encryptor, CryptoStreamMode.Write);
             using (var streamWriter = new StreamWriter(this.cryptoStream))
             {
                 streamWriter.Write(plaintext);
             }
            return memoryStream.ToArray();
        }

       public void Dispose()
        { 
             this.Dispose(true);
             GC.SuppressFinalize(this);
        }

       protected virtual void Dispose(bool disposing)
        {
            if (disposing)
            {
                if (this.memoryStream != null)
                {
                    this.memoryStream.Dispose();
                }

                if (this.cryptoStream != null)
                {
                    this.cryptoStream.Dispose();
                }
            }
        }
   }

0

অফ-টপিক তবে আমি আপনাকে গ্রুপিংয়ের জন্য আলাদা বিন্যাসের কৌশলটি ব্যবহার করার পরামর্শ দিচ্ছি using:

using (var memoryStream = new MemoryStream())
{
    using (var cryptograph = new DESCryptoServiceProvider())
    using (var encryptor = cryptograph.CreateEncryptor(key, iv))
    using (var cryptoStream = new CryptoStream(memoryStream, encryptor, CryptoStreamMode.Write))
    using (var streamWriter = new StreamWriter(cryptoStream))
    {
        streamWriter.Write(data);
    }

    return memoryStream.ToArray();
}

varসত্যিকারের দীর্ঘ শ্রেণীর নামের পুনরাবৃত্তি এড়াতে আমি এখানে ব্যবহার করার পক্ষেও পরামর্শ দিই ।

দ্রষ্টব্য ইশারা আমি প্রথম ফেরত ধনুর্বন্ধনী করতে @ShellShock ধন্যবাদ usingএটা করতে হবে যেমন memoryStreamমধ্যে returnসাধ্যের বাইরে বিবৃতি।


5
স্মৃতিপ্রবাহ? টোআররে () সুযোগের বাইরে থাকবে না?
পলিফুন

এটি কোডের মূল অংশের সাথে একেবারে সমান। আমি কেবল কোঁকড়া ধনুর্বন্ধনী বাদ দিয়েছি, অনেকটা আপনি ifএস দিয়ে এটি করতে পারেন (যদিও আমি এই কৌশলটি usingএস ব্যতীত অন্য কোনও কিছুর জন্য পরামর্শ দেব না )।
ড্যান আব্রামভ

2
মূল কোডটিতে, মেমোরিস্ট্রিম.টোআর্রে () প্রথম ব্যবহারের সুযোগের ভিতরে ছিল; আপনি এটা সুযোগের বাইরে পেয়েছেন।
পলিফুন

আপনাকে অনেক ধন্যবাদ, আমি ঠিক বুঝতে পেরেছি আপনি returnবক্তব্য বোঝাতে চাইছেন। আসলেই সত্য. আমি এর প্রতিফলিত করতে উত্তর সম্পাদনা করেছি।
ড্যান আব্রামভ

আমি ব্যক্তিগতভাবে মনে করি যে usingবন্ধনীবিহীন কোডগুলি কোডটিকে আরও ভঙ্গুর করে তোলে (বছরের কয়েক বছর ধরে আলাদা হয়ে যায় এবং একত্রীভূত হয়)। joelonsoftware.com/2005/05/11/making-wrong-code-look-wrong & imperialviolet.org/2014/02/22/applebug.html
টিম আবেল

0

সমস্ত ব্যবহার বন্ধ করুন এবং নেস্টেড ডিসপোজ-কলগুলি ব্যবহার করুন!

    public static byte[] Encrypt(string data, byte[] key, byte[] iv)
    {
        MemoryStream memoryStream = null;
        DESCryptoServiceProvider cryptograph = null;
        CryptoStream cryptoStream = null;
        StreamWriter streamWriter = null;

        try
        {
            memoryStream = new MemoryStream();
            cryptograph = new DESCryptoServiceProvider();
            cryptoStream = new CryptoStream(memoryStream, cryptograph.CreateEncryptor(key, iv), CryptoStreamMode.Write);
            streamWriter = new StreamWriter(cryptoStream);

            streamWriter.Write(data);
            return memoryStream.ToArray();
        }
        finally 
        {
            if(streamWriter != null)
                streamWriter.Dispose();
            else if(cryptoStream != null)
                cryptoStream.Dispose();
            else if(memoryStream != null)
                memoryStream.Dispose();

            if (cryptograph != null)
                cryptograph.Dispose();
        }
    }

1
usingএই ক্ষেত্রে আপনার কেন এড়ানো উচিত দয়া করে তা ব্যাখ্যা করুন ।
StuperUser

1
আপনি ব্যবহার-বিবৃতিটি মাঝখানে রাখতে পারেন, তবে আপনাকে অন্যটি সমাধান করতে হবে। একটি যৌক্তিক সুসঙ্গত পেতে এবং সমস্ত দিকগুলিতে আপগ্রেডযোগ্য সমাধানে আমি সমস্ত usings মুছে ফেলার সিদ্ধান্ত নিয়েছি!
হ্যারি সালটজম্যান

0

আমি কেবল কোডটি আনপ্রেপ করতে চেয়েছিলাম যাতে আমরা Disposeবস্তুগুলিতে একাধিক কল দেখতে পারি :

memoryStream = new MemoryStream()
cryptograph = new DESCryptoServiceProvider()
cryptoStream = new CryptoStream()
streamWriter = new StreamWriter()

memoryStream.Dispose(); //implicitly owned by cryptoStream
cryptoStream.Dispose(); //implicitly owned by streamWriter
streamWriter.Dispose(); //through a using

cryptoStream.Dispose(); //INVALID: second dispose through using
cryptograph.Dispose(); //through a using
memorySTream.Dipose(); //INVALID: second dispose through a using

return memoryStream.ToArray(); //INVALID: accessing disposed memoryStream

যদিও বেশির ভাগ .NET শ্রেণী (আশা) একাধিক কল ভুল বিরুদ্ধে প্রাণবন্ত .Dispose, না সব শ্রেণীর প্রোগ্রামার অপব্যবহারের বিরুদ্ধে আত্মরক্ষামূলক মতো থাকে।

এফএক্স কপ এটি জানে এবং আপনাকে সতর্ক করে।

আপনার কয়েকটি পছন্দ আছে;

  • যে Disposeকোনও বস্তুতে কেবল একবার কল করুন; ব্যবহার করবেন নাusing
  • দুবার নিষ্পত্তি কল করতে থাকুন এবং আশা করুন কোডটি ক্রাশ হবে না
  • সতর্কতা দমন

-1

আমি এই জাতীয় কোড ব্যবহার করেছি যা বাইট [] এবং স্ট্রিম ব্যবহার না করেই বাইট [] ফেরায় takes

public static byte[] Encrypt(byte[] data, byte[] key, byte[] iv)
{
  DES des = new DES();
  des.BlockSize = 128;
  des.Mode = CipherMode.CBC;
  des.Padding = PaddingMode.Zeros;
  des.IV = IV
  des.Key = key
  ICryptoTransform encryptor = des.CreateEncryptor();

  //and finaly operations on bytes[] insted of streams
  return encryptor.TransformFinalBlock(plaintextarray,0,plaintextarray.Length);
}

এইভাবে আপনাকে যা করতে হবে তা হ'ল এনকোডিংগুলি ব্যবহার করে স্ট্রিং থেকে বাইটে রূপান্তর করা।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.