आप प्रतिबिंब का उपयोग करके इस लक्ष्य को हासिल कर सकते हैं
तो तुम कुछ इस तरह हो सकता था।
लाभ: रखरखाव। प्रतिलिपि बनाने वाले या समान, गुण जोड़ने या हटाने के लिए कोई ज़रूरत नहीं है।
नुकसान: प्रदर्शन। प्रतिबिंब धीमा है। हम अभी भी औसत आकार के वर्गों पर मिलीसेकंड की बात कर रहे हैं।
यहाँ एक प्रतिबिंब आधारित उथले प्रति कॉपी-टू-उपवर्ग समर्थन कार्यान्वयन है, विस्तार तरीकों का उपयोग कर:
public static TOut GetShallowCopyByReflection<TOut>(this Object objIn)
{
Type inputType = objIn.GetType();
Type outputType = typeof(TOut);
if (!outputType.Equals(inputType) && !outputType.IsSubclassOf(inputType)) throw new ArgumentException(String.Format("{0} is not a sublcass of {1}", outputType, inputType));
PropertyInfo[] properties = inputType.GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.FlattenHierarchy);
FieldInfo[] fields = inputType.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.FlattenHierarchy);
TOut objOut = (TOut)Activator.CreateInstance(typeof(TOut));
foreach (PropertyInfo property in properties)
{
try
{
property.SetValue(objIn, property.GetValue(objIn, null), null);
}
catch (ArgumentException) { } // For Get-only-properties
}
foreach (FieldInfo field in fields)
{
field.SetValue(objOut, field.GetValue(objIn));
}
return objOut;
}
इस विधि सभी की प्रतिलिपि बनाएगा - निजी और सार्वजनिक, साथ ही सभी क्षेत्रों। गुणों को संदर्भ द्वारा प्रतिलिपि बनाई जाती है, इसे एक उथली प्रतिलिपि बनाते हैं।
ईकाई परीक्षण:
[TestClass]
public class ExtensionTests {
[TestMethod]
public void GetShallowCloneByReflection_PropsAndFields()
{
var uri = new Uri("http://www.stackoverflow.com");
var source = new TestClassParent();
source.SomePublicString = "Pu";
source.SomePrivateString = "Pr";
source.SomeInternalString = "I";
source.SomeIntField = 6;
source.SomeList = new List<Uri>() { uri };
var dest = source.GetShallowCopyByReflection<TestClassChild>();
Assert.AreEqual("Pu", dest.SomePublicString);
Assert.AreEqual("Pr", dest.SomePrivateString);
Assert.AreEqual("I", dest.SomeInternalString);
Assert.AreEqual(6, dest.SomeIntField);
Assert.AreSame(source.SomeList, dest.SomeList);
Assert.AreSame(uri, dest.SomeList[0]);
}
}
internal class TestClassParent
{
public String SomePublicString { get; set; }
internal String SomeInternalString { get; set; }
internal String SomePrivateString { get; set; }
public String SomeGetOnlyString { get { return "Get"; } }
internal List<Uri> SomeList { get; set; }
internal int SomeIntField;
}
internal class TestClassChild : TestClassParent {}
उत्तर के लिए धन्यवाद। मैं इसके लिए एक स्वचालित तरीका ढूंढ रहा था लेकिन आप सुझाव दे रहे हैं कि ऐसा कोई नहीं है। :( – Vizu
दुर्भाग्य से, नहीं। आप एक निर्माता या कुछ फार्म का एक कारखाना विधि जोड़ने की आवश्यकता होगी। –
@Vizu जो विधि आप को अपनाने की थी, मैं भी चाहता हूँ कुछ इसी तरह, कृपया यहाँ डाल आप इसे –