সি # তে জেনেরিক পদ্ধতি তৈরি করা হচ্ছে


86

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

আমার এখন যা আছে তা এখানে। তবে, যদি একটি সংখ্যার মানটি অবৈধ হয় এবং এটি দুর্ভাগ্যক্রমে আমার পরিস্থিতিতে একটি বৈধ মান হয় তবে এটি 0 ছাড়িয়ে যাবে। কেউ আমাকে সাহায্য করতে পারেন? ধন্যবাদ!

public static T GetQueryString<T>(string key) where T : IConvertible
{
    T result = default(T);

    if (String.IsNullOrEmpty(HttpContext.Current.Request.QueryString[key]) == false)
    {
        string value = HttpContext.Current.Request.QueryString[key];

        try
        {
            result = (T)Convert.ChangeType(value, typeof(T));  
        }
        catch
        {
            //Could not convert.  Pass back default value...
            result = default(T);
        }
    }

    return result;
}

তিনি একাধিক বাস্তবায়ন পোর্ট করছেন, সুতরাং পুরাতন কার্যকারিতাটি কল করুন, ফলাফলটি মনে করুন, নতুন কার্যকারিতাটি কল করুন, ফলাফলটি মনে রাখবেন, তুলনা করুন। এখন এটি 100 বার এলোমেলো ইনপুটগুলির সাথে এবং ভয়েলা!
হামিশ গ্রুবিজন

আমি দুঃখিত, আমি এখনও বুঝতে পারি না যে এটি এই ক্ষেত্রে কীভাবে প্রযোজ্য। আমি এখনও ফাংশনটি কাজ করার জন্য চেষ্টা করছি।
মাইক কোল

উত্তরের দিকে তাকিয়ে আমি কিছুটা বিভ্রান্ত: আপনার কলাররা কি ইনট বা ইন্ট ব্যবহার করে প্যারামিটারাইজ করছে? টি হিসাবে?

আমার কাছে মনে হচ্ছে, অভ্যন্তরীণভাবে এটি পরিচালনা করার পরিবর্তে, আপনাকে এই পদ্ধতিটি ব্যতিক্রম ছুঁড়ে দেওয়ার অনুমতি দেওয়া উচিত। সম্ভবত এটি কেবল আমিই, তবে কেউ বিভ্রান্ত হতে পারে কেন তাদের কলটি সর্বদা ডিফল্ট মানটি ফিরিয়ে দেয় কারণ তারা ChangeTypeব্যর্থ হওয়ার পরে উত্পন্ন ব্যতিক্রমটি দেখছেন না ।
ক্রাশ করুন

উত্তর:


65

আপনি যদি ডিফল্ট (টি) ব্যবহার না করে প্রত্যাবর্তনের জন্য ডিফল্ট মান নির্দিষ্ট করেন?

public static T GetQueryString<T>(string key, T defaultValue) {...}

এটি এটিকে কল করাও সহজ করে তোলে:

var intValue = GetQueryString("intParm", Int32.MinValue);
var strValue = GetQueryString("strParm", "");
var dtmValue = GetQueryString("dtmPatm", DateTime.Now); // eg use today's date if not specified

অবৈধ / নিখোঁজ ক্যোরিস্ট্রিংয়ের মানগুলি বোঝাতে আপনার যান্ত্রিক মানগুলির দরকার।


হ্যাঁ, কোনও পূর্ণসংখ্যার ডিফল্ট মানের উপর নির্ভর করার চেয়ে এটি আরও কার্যকর seems আমি এটা মনে রাখব। আমি এখনও আমার মূল ফাংশনটি সব ধরণের জন্য কাজ করার প্রত্যাশা করছি, যদিও আমি অ-জেনেরিক ফাংশনগুলি ব্যবহার করতে পারি ort
মাইক কোলে

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

4
কীভাবে এর মূল্য পেতে হয়: long ? testযেখানে ডিফল্টটি বাতিল হওয়া উচিত
আরশাদ

16

আমি জানি, আমি জানি, কিন্তু ...

public static bool TryGetQueryString<T>(string key, out T queryString)

4
Try-Pattern ভাল কোন .NET বিকাশকারীর কাছে পরিচিত করতে হবে। আপনি আমাকে জিজ্ঞাসা করলে এটি খারাপ জিনিস নয়। এফ # বা নেট 4.0 এ আপনি বিকল্প (বা পছন্দ) ব্যবহার করবেন
ক্রিশ্চিয়ান ক্লাউজার

6
যদি অন্য কোনও কারণে না হয় তবে আমি এড়াতে চেষ্টা করি কারণ আউটপুট ভেরিয়েবলটি "প্রাক-ঘোষণা" করা আমি ঘৃণা করি, বিশেষত এটি যদি কখনও ব্যবহার নাও হয় - অন্যথায় কী কোডের একটি নিখুঁতভাবে ভাল লাইন হতে পারে তার অপচয়।
জে

প্রকৃতপক্ষে এটি আপনার সমস্যা সমাধানের সহজতম উপায় - উপরের মত দুটি ফাংশনটি সংজ্ঞায়িত করুন - দু'জন সহায়ক যা এই ফাংশনটি ব্যবহার করবেন (সেগুলি 4 টি লাইনার হবে)।
গ্রীনল্ডম্যান

4
আমি জে যেমন বলেছিলেন একই কারণে চেষ্টা প্যাটার্নকে ঘৃণা করি। আমি যদি সম্ভব হয় তবে একটি জেনেরিক ফাংশন পছন্দ করবো, এটি ছিল আমার আসল লক্ষ্য।
মাইক কোল

11
করুক না করুক, চেষ্টা নেই! <Yoda>
খরগোশ

12

এই সম্পর্কে কি? থেকে রিটার্ন টাইপ পরিবর্তন Tকরার জন্যNullable<T>

public static Nullable<T> GetQueryString<T>(string key) where T : struct, IConvertible
        {
            T result = default(T);

            if (String.IsNullOrEmpty(HttpContext.Current.Request.QueryString[key]) == false)
            {
                string value = HttpContext.Current.Request.QueryString[key];

                try
                {
                    result = (T)Convert.ChangeType(value, typeof(T));  
                }
                catch
                {
                    //Could not convert.  Pass back default value...
                    result = default(T);
                }
            }

            return result;
        }

ত্রুটি: জেনেরিক টাইপ বা পদ্ধতিতে 'সিস্টেম.নু' <টি> 'প্যারামিটার' টি 'হিসাবে এটি ব্যবহার করতে টাইপ' টি 'অবশ্যই একটি নন-অযোগ্য মান ধরণ হতে হবে।
মাইক কোল

আপনাকেও নির্দিষ্ট করা দরকার where T : struct
অ্যারোনআউট

@ মাইক সি: আপনার একই ত্রুটি হওয়া উচিত নয়। সম্পাদিত কোড অবশ্যই সংকলন করে।
অ্যারোনআউট

হ্যাঁ, এখন পেয়েছি সুতরাং আমি যখন স্ট্রিং টাইপের জন্য এটি কল করতে চাই তখন কী ঘটে? এটি এখনকার মতো গ্রহণ করবে না।
মাইক কোল

@ মাইকিস, এটি সম্ভব বলে মনে করবেন না কারণ stringএটি একটি nullableমান
গ্রাভিটন

5

আপনি এক প্রকারের মোনাদ ব্যবহার করতে পারেন (যদিও আমি জয়ের উত্তর পছন্দ করি)

public class Maybe<T>
{
    private readonly T _value;

    public Maybe(T value)
    {
        _value = value;
        IsNothing = false;
    }

    public Maybe()
    {
        IsNothing = true;
    }

    public bool IsNothing { get; private set; }

    public T Value
    {
        get
        {
            if (IsNothing)
            {
                throw new InvalidOperationException("Value doesn't exist");
            }
            return _value;
        }
    }

    public override bool Equals(object other)
    {
        if (IsNothing)
        {
            return (other == null);
        }
        if (other == null)
        {
            return false;
        }
        return _value.Equals(other);
    }

    public override int GetHashCode()
    {
        if (IsNothing)
        {
            return 0;
        }
        return _value.GetHashCode();
    }

    public override string ToString()
    {
        if (IsNothing)
        {
            return "";
        }
        return _value.ToString();
    }

    public static implicit operator Maybe<T>(T value)
    {
        return new Maybe<T>(value);
    }

    public static explicit operator T(Maybe<T> value)
    {
        return value.Value;
    }
}

আপনার পদ্ধতিটি দেখতে এমন হবে:

    public static Maybe<T> GetQueryString<T>(string key) where T : IConvertible
    {
        if (String.IsNullOrEmpty(HttpContext.Current.Request.QueryString[key]) == false)
        {
            string value = HttpContext.Current.Request.QueryString[key];

            try
            {
                return (T)Convert.ChangeType(value, typeof(T));
            }
            catch
            {
                //Could not convert.  Pass back default value...
                return new Maybe<T>();
            }
        }

        return new Maybe<T>();
    }

4

Convert.ChangeType().NET 2.0 বিসিএল-এ অযোগ্য প্রকারগুলি বা গণনাগুলি সঠিকভাবে পরিচালনা করে না (আমি মনে করি এটি বিসিএল ৪.০ এর জন্য স্থির হয়েছে)। বাহ্যিক বাস্তবায়ন আরও জটিল করার পরিবর্তে রূপান্তরকারীটিকে আপনার জন্য আরও কাজ করতে বাধ্য করুন। এখানে আমি ব্যবহার করছি একটি বাস্তবায়ন:

public static class Converter
{
  public static T ConvertTo<T>(object value)
  {
    return ConvertTo(value, default(T));
  }

  public static T ConvertTo<T>(object value, T defaultValue)
  {
    if (value == DBNull.Value)
    {
      return defaultValue;
    }
    return (T) ChangeType(value, typeof(T));
  }

  public static object ChangeType(object value, Type conversionType)
  {
    if (conversionType == null)
    {
      throw new ArgumentNullException("conversionType");
    }

    // if it's not a nullable type, just pass through the parameters to Convert.ChangeType
    if (conversionType.IsGenericType && conversionType.GetGenericTypeDefinition().Equals(typeof(Nullable<>)))
    {
      // null input returns null output regardless of base type
      if (value == null)
      {
        return null;
      }

      // it's a nullable type, and not null, which means it can be converted to its underlying type,
      // so overwrite the passed-in conversion type with this underlying type
      conversionType = Nullable.GetUnderlyingType(conversionType);
    }
    else if (conversionType.IsEnum)
    {
      // strings require Parse method
      if (value is string)
      {
        return Enum.Parse(conversionType, (string) value);          
      }
      // primitive types can be instantiated using ToObject
      else if (value is int || value is uint || value is short || value is ushort || 
           value is byte || value is sbyte || value is long || value is ulong)
      {
        return Enum.ToObject(conversionType, value);
      }
      else
      {
        throw new ArgumentException(String.Format("Value cannot be converted to {0} - current type is " +
                              "not supported for enum conversions.", conversionType.FullName));
      }
    }

    return Convert.ChangeType(value, conversionType);
  }
}

তারপরে আপনার getQueryString <T> এর বাস্তবায়ন হতে পারে:

public static T GetQueryString<T>(string key)
{
    T result = default(T);
    string value = HttpContext.Current.Request.QueryString[key];

    if (!String.IsNullOrEmpty(value))
    {
        try
        {
            result = Converter.ConvertTo<T>(value);  
        }
        catch
        {
            //Could not convert.  Pass back default value...
            result = default(T);
        }
    }

    return result;
}

0

আমি এই শ্রেণীর সেটিংসের মতো ক্লাস দিয়ে শুরু করতে চাই {পাবলিক ইন এক্স {গেট; সেট;} পাবলিক স্ট্রিং ওয়াই {গেট; সেট } // প্রয়োজনীয় হিসাবে পুনরাবৃত্তি

 public settings()
 {
    this.X = defaultForX;
    this.Y = defaultForY;
    // repeat ...
 }
 public void Parse(Uri uri)
 {
    // parse values from query string.
    // if you need to distinguish from default vs. specified, add an appropriate property

 }

এটি 100 এর প্রকল্পগুলিতে ভাল কাজ করেছে। মানগুলি পার্স করার জন্য আপনি অন্যান্য অনেকগুলি পার্সিং সমাধান ব্যবহার করতে পারেন।

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