স্ট্রিংয়ের মান সহ প্রতিবিম্ব দ্বারা একটি সম্পত্তি সেট করা


312

আমি টাইপের মান সহ প্রতিবিম্বের মাধ্যমে কোনও সামগ্রীর সম্পত্তি সেট করতে চাই string। সুতরাং, উদাহরণস্বরূপ, আমি একটি আছে অনুমান করা Shipএকটি সম্পত্তি সঙ্গে, বর্গ Latitude, যা একটি হল double

আমি যা করতে চাই তা এখানে:

Ship ship = new Ship();
string value = "5.5";
PropertyInfo propertyInfo = ship.GetType().GetProperty("Latitude");
propertyInfo.SetValue(ship, value, null);

যেমনটি, এটি একটি নিক্ষেপ করে ArgumentException:

টাইপ 'সিস্টেম.স্ট্রিং' এর অবজেক্টটি 'সিস্টেম.ডুবল' টাইপে রূপান্তর করা যায় না।

আমি কীভাবে মানকে যথাযথ প্রকারে রূপান্তর করতে পারি propertyInfo?


1
আপনার জন্য প্রশ্ন: এটি একটি কাস্টম ORM সমাধানের অংশ?
ব্যবহারকারী3308043

উত্তর:


527

আপনি ব্যবহার করতে পারেন Convert.ChangeType()- IConvertibleউপস্থাপনা ফর্ম্যাটগুলি পরিবর্তন করতে এটি কোনও ধরণের রানটাইম তথ্য ব্যবহারের অনুমতি দেয় । যদিও সমস্ত রূপান্তর সম্ভব নয়, এবং আপনি যদি বিশেষ ধরণের রূপান্তরগুলিকে সমর্থন না করতে চান তবে বিশেষ কেস যুক্তি লেখার দরকার হতে পারে IConvertible

সম্পর্কিত কোড (ব্যতিক্রম হ্যান্ডলিং বা বিশেষ ক্ষেত্রে যুক্তি ছাড়াই) হবে:

Ship ship = new Ship();
string value = "5.5";
PropertyInfo propertyInfo = ship.GetType().GetProperty("Latitude");
propertyInfo.SetValue(ship, Convert.ChangeType(value, propertyInfo.PropertyType), null);

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

আছে TryChangeTypeনাকি CanChangeType?
শিমি ওয়েটজ্যান্ডলার

34

বেশ কয়েকজন যেমন বলেছেন, আপনি ব্যবহার করতে চান Convert.ChangeType:

propertyInfo.SetValue(ship,
    Convert.ChangeType(value, propertyInfo.PropertyType),
    null);

আসলে, আমি আপনাকে পুরো Convertক্লাসটি দেখার পরামর্শ দিচ্ছি ।

এই শ্রেণি এবং অন্যান্য অনেকগুলি দরকারী ক্লাস Systemনেমস্পেসের অংশ । আমি প্রতি বছর বা আরও কিছু নাম বাদ দিয়ে স্ক্যান করা দরকারী মনে করি যেগুলি কী বৈশিষ্ট্যগুলি মিস করেছি find একবার চেষ্টা করে দেখো!


1
কোনও স্ট্রিং থেকে সুস্পষ্ট রূপান্তর আছে এমন কোনও ধরণের সম্পত্তি সেট করার জন্য ওপি সম্ভবত সাধারণ উত্তর চায়।
ড্যানিয়েল আরউইকার

ভাল যুক্তি. আমি সম্পাদনা করব এবং প্রকৃত উত্তরদাতাদের দিকে নির্দেশ করব, বা আমার নামের স্থানের বাকী অংশ সম্পর্কে আমি যা বলেছি তা যদি কেউ যুক্ত করে তবে আমার মুছে ফেলব।
জন স্যান্ডার্স

19

আমি লক্ষ করেছি যে প্রচুর লোকেরা সুপারিশ করছে Convert.ChangeType- এটি কিছু ক্ষেত্রে কার্যকর হয় তবে যত তাড়াতাড়ি আপনি nullableপ্রকারের সাথে জড়িত হওয়া শুরু করবেন আপনি InvalidCastExceptions:

http://weblogs.asp.net/pjohnson/archive/2006/02/07/Convert.ChangeType-doesn_2700_t-handle-nullables.aspx

এটি পরিচালনা করার জন্য কয়েক বছর আগে একটি মোড়ক লেখা হয়েছিল তবে এটিও নিখুঁত নয়।

http://weblogs.asp.net/pjohnson/archive/2006/02/07/Convert.ChangeType-doesn_2700_t-handle-nullables.aspx


13

আমি এল বুশকিনের কাছ থেকে উত্তরটি চেষ্টা করেছিলাম এবং এটি দুর্দান্ত কাজ করেছে, তবে এটি নাল মান এবং নল ক্ষেত্রের জন্য কাজ করবে না। সুতরাং আমি এটিকে এটিতে পরিবর্তন করেছি:

propertyName= "Latitude";
PropertyInfo propertyInfo = ship.GetType().GetProperty(propertyName);
if (propertyInfo != null)
{
     Type t = Nullable.GetUnderlyingType(propertyInfo.PropertyType) ?? propertyInfo.PropertyType;
     object safeValue = (value == null) ? null : Convert.ChangeType(value, t);
     propertyInfo.SetValue(ship, safeValue, null);
}

আমি এই কেসটি পূরণ করার সাথে সাথে আপনাকে ধন্যবাদ বলতে হবে এবং এটিই একমাত্র সমাধান। ধন্যবাদ ~!
ফ্রাংভা

11

আপনি একটি ধরণের রূপান্তরকারী ব্যবহার করতে পারেন (কোনও ত্রুটি যাচাই করে নেই):

Ship ship = new Ship();
string value = "5.5";
var property = ship.GetType().GetProperty("Latitude");
var convertedValue = property.Converter.ConvertFrom(value);
property.SetValue(self, convertedValue);

কোডটি সংগঠিত করার ক্ষেত্রে, আপনি এমন এক ধরনের মিশ্রণ তৈরি করতে পারেন যা এরকম কোডের ফলস্বরূপ:

Ship ship = new Ship();
ship.SetPropertyAsString("Latitude", "5.5");

এটি এই কোড দিয়ে অর্জন করা হবে:

public interface MPropertyAsStringSettable { }
public static class PropertyAsStringSettable {
  public static void SetPropertyAsString(
    this MPropertyAsStringSettable self, string propertyName, string value) {
    var property = TypeDescriptor.GetProperties(self)[propertyName];
    var convertedValue = property.Converter.ConvertFrom(value);
    property.SetValue(self, convertedValue);
  }
}

public class Ship : MPropertyAsStringSettable {
  public double Latitude { get; set; }
  // ...
}

MPropertyAsStringSettable বিভিন্ন শ্রেণীর জন্য পুনরায় ব্যবহার করা যেতে পারে।

আপনার নিজস্ব বৈশিষ্ট্য বা শ্রেণীতে সংযুক্ত করতে আপনি নিজস্ব কাস্টম ধরণের রূপান্তরকারীও তৈরি করতে পারেন :

public class Ship : MPropertyAsStringSettable {
  public Latitude Latitude { get; set; }
  // ...
}

[TypeConverter(typeof(LatitudeConverter))]
public class Latitude { ... }

আপনি কেবল ব্যবহারের পরিবর্তে চিহ্নিতকারী অন্তর্ভুক্ত করেছেন কেন এমন কোনও বিশেষ কারণ আছে object?
গ্রো

1
হ্যাঁ, চিহ্নিতকারী ইন্টারফেসটি এক্সটেনশন পদ্ধতিগুলিতে যুক্ত করার জন্য স্থানধারক হিসাবে কাজ করে। ব্যবহারের objectফলে সমস্ত শ্রেণিতে এক্সটেনশন পদ্ধতি যুক্ত হবে, যা সাধারণত কাম্য নয়।
জর্দো

6

আপনি সম্ভবত Convert.ChangeTypeপদ্ধতিটি সন্ধান করছেন। উদাহরণ স্বরূপ:

Ship ship = new Ship();
string value = "5.5";
PropertyInfo propertyInfo = ship.GetType().GetProperty("Latitude");
propertyInfo.SetValue(ship, Convert.ChangeType(value, propertyInfo.PropertyType), null);

5

ব্যবহার করে Convert.ChangeTypeএবং থেকে রূপান্তর করতে টাইপ পাচ্ছেন PropertyInfo.PropertyType

propertyInfo.SetValue( ship,
                       Convert.ChangeType( value, propertyInfo.PropertyType ),
                       null );

4

আমি সাধারণ উত্তর দিয়ে এর উত্তর দেব। সাধারণত এই উত্তরগুলি গাইডের সাথে কাজ করে না। এখানে গাইডগুলির সাথে একটি কার্যকারী সংস্করণ রয়েছে।

var stringVal="6e3ba183-89d9-e611-80c2-00155dcfb231"; // guid value as string to set
var prop = obj.GetType().GetProperty("FooGuidProperty"); // property to be setted
var propType = prop.PropertyType;

// var will be type of guid here
var valWithRealType = TypeDescriptor.GetConverter(propType).ConvertFrom(stringVal); 

1
এটি গ্রহণযোগ্য উত্তর হওয়া উচিত। এটি জিআইওডি <3 এর সাথেও কাজ করে। ধন্যবাদ, আলী (এটি আমার মেয়ের ডাক নাম)
ক্যাটলিন রাডোই

3

অথবা আপনি চেষ্টা করতে পারেন:

propertyInfo.SetValue(ship, Convert.ChangeType(value, propertyInfo.PropertyType), null);

//But this will cause problems if your string value IsNullOrEmplty...

2

আপনি যদি মেট্রো অ্যাপ্লিকেশন লিখছেন তবে আপনার অন্যান্য কোড ব্যবহার করা উচিত:

Ship ship = new Ship();
string value = "5.5";
PropertyInfo propertyInfo = ship.GetType().GetTypeInfo().GetDeclaredProperty("Latitude");
propertyInfo.SetValue(ship, Convert.ChangeType(value, propertyInfo.PropertyType));

বিঃদ্রঃ:

ship.GetType().GetTypeInfo().GetDeclaredProperty("Latitude");

পরিবর্তে

ship.GetType().GetProperty("Latitude");

0

নিম্নলিখিত কোড ব্যবহার করা আপনার সমস্যার সমাধান করা উচিত:

item.SetProperty(prop.Name, Convert.ChangeType(item.GetProperty(prop.Name).ToString().Trim(), prop.PropertyType));

-9

আপনি কি প্রতিবিম্বের সাথে চারপাশে খেলতে খুঁজছেন বা আপনি কোনও সফ্টওয়্যার তৈরির প্রযোজনা তৈরি করতে চাইছেন? আপনি কেন একটি সম্পত্তি সেট করতে প্রতিবিম্ব ব্যবহার করছেন তা আমি প্রশ্ন করব।

Double new_latitude;

Double.TryParse (value, out new_latitude);
ship.Latitude = new_latitude;

1
লোকেরা যা করার চেষ্টা করে এবং আপনারা কী ভাবেন যে তাদের অবশ্যই করা উচিত তা আপনাকে সম্মান করা উচিত। Downvoted। (এইখান থেকে GenericProgramming.exe:ReflectionBenefits())
Петър Петров
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.