diff --git a/Ical.Net.Benchmarks/Ical.Net.Benchmarks.csproj b/Ical.Net.Benchmarks/Ical.Net.Benchmarks.csproj
index 18d709ea..1659d678 100644
--- a/Ical.Net.Benchmarks/Ical.Net.Benchmarks.csproj
+++ b/Ical.Net.Benchmarks/Ical.Net.Benchmarks.csproj
@@ -1,17 +1,13 @@
-
-
- net8.0;net6.0;netcoreapp3.1;net48
- Exe
- latest
-
-
-
-
-
-
-
-
-
-
+
+ net8.0;net6.0;netcoreapp3.1;net48
+ Exe
+ latest
+
+
+
+
+
+
+
diff --git a/Ical.Net.Tests/CopyComponentTests.cs b/Ical.Net.Tests/CopyComponentTests.cs
new file mode 100644
index 00000000..0fbeb512
--- /dev/null
+++ b/Ical.Net.Tests/CopyComponentTests.cs
@@ -0,0 +1,198 @@
+using Ical.Net.CalendarComponents;
+using Ical.Net.DataTypes;
+using Ical.Net.Serialization;
+using NUnit.Framework;
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Text.RegularExpressions;
+
+namespace Ical.Net.Tests
+{
+ ///
+ /// Tests for deep copying of ICal components.
+ ///
+ [TestFixture]
+ public class CopyComponentTests
+ {
+ [Test, TestCaseSource(nameof(CopyCalendarTest_TestCases)), Category("Copy tests")]
+ public void CopyCalendarTest(string calendarString)
+ {
+ var iCal1 = Calendar.Load(calendarString);
+ var iCal2 = iCal1.Copy();
+ SerializationTests.CompareCalendars(iCal1, iCal2);
+ }
+
+ public static IEnumerable CopyCalendarTest_TestCases()
+ {
+ yield return new TestCaseData(IcsFiles.Attachment3).SetName("Attachment3");
+ yield return new TestCaseData(IcsFiles.Bug2148092).SetName("Bug2148092");
+ yield return new TestCaseData(IcsFiles.CaseInsensitive1).SetName("CaseInsensitive1");
+ yield return new TestCaseData(IcsFiles.CaseInsensitive2).SetName("CaseInsensitive2");
+ yield return new TestCaseData(IcsFiles.CaseInsensitive3).SetName("CaseInsensitive3");
+ yield return new TestCaseData(IcsFiles.Categories1).SetName("Categories1");
+ yield return new TestCaseData(IcsFiles.Duration1).SetName("Duration1");
+ yield return new TestCaseData(IcsFiles.Encoding1).SetName("Encoding1");
+ yield return new TestCaseData(IcsFiles.Event1).SetName("Event1");
+ yield return new TestCaseData(IcsFiles.Event2).SetName("Event2");
+ yield return new TestCaseData(IcsFiles.Event3).SetName("Event3");
+ yield return new TestCaseData(IcsFiles.Event4).SetName("Event4");
+ yield return new TestCaseData(IcsFiles.GeographicLocation1).SetName("GeographicLocation1");
+ yield return new TestCaseData(IcsFiles.Language1).SetName("Language1");
+ yield return new TestCaseData(IcsFiles.Language2).SetName("Language2");
+ yield return new TestCaseData(IcsFiles.Language3).SetName("Language3");
+ yield return new TestCaseData(IcsFiles.TimeZone1).SetName("TimeZone1");
+ yield return new TestCaseData(IcsFiles.TimeZone2).SetName("TimeZone2");
+ yield return new TestCaseData(IcsFiles.TimeZone3).SetName("TimeZone3");
+ yield return new TestCaseData(IcsFiles.XProperty1).SetName("XProperty1");
+ yield return new TestCaseData(IcsFiles.XProperty2).SetName("XProperty2");
+ }
+
+ private static readonly DateTime _now = DateTime.Now;
+ private static readonly DateTime _later = _now.AddHours(1);
+
+ private static CalendarEvent GetSimpleEvent() => new CalendarEvent
+ {
+ DtStart = new CalDateTime(_now),
+ DtEnd = new CalDateTime(_later),
+ Duration = TimeSpan.FromHours(1),
+ };
+
+ private static string SerializeEvent(CalendarEvent e) => new CalendarSerializer().SerializeToString(new Calendar { Events = { e } });
+
+ [Test]
+ public void CopyCalendarEventTest()
+ {
+ var orig = GetSimpleEvent();
+ orig.Uid = "Hello";
+ orig.Summary = "Original summary";
+ orig.Resources = new[] { "A", "B" };
+ orig.GeographicLocation = new GeographicLocation(48.210033, 16.363449);
+ orig.Transparency = TransparencyType.Opaque;
+ orig.Attachments.Add(new Attachment("https://original.org/"));
+ var copy = orig.Copy();
+
+ copy.Uid = "Goodbye";
+ copy.Summary = "Copy summary";
+
+ var resourcesCopyFromOrig = new List(copy.Resources);
+ copy.Resources = new[] { "C", "D" };
+ copy.Attachments[0].Uri = new Uri("https://copy.org/");
+ const string uidPattern = "UID:";
+ var serializedOrig = SerializeEvent(orig);
+ var serializedCopy = SerializeEvent(copy);
+
+ Assert.Multiple(() =>
+ {
+ // Should be a deep copy and changes only apply to the copy instance
+ Assert.That(copy.Uid, Is.Not.EqualTo(orig.Uid));
+ Assert.That(copy.Summary, Is.Not.EqualTo(orig.Summary));
+ Assert.That(copy.Attachments[0].Uri, Is.Not.EqualTo(orig.Attachments[0].Uri));
+ Assert.That(copy.Resources[0], Is.Not.EqualTo(orig.Resources[0]));
+
+ Assert.That(resourcesCopyFromOrig, Is.EquivalentTo(orig.Resources));
+ Assert.That(copy.GeographicLocation, Is.EqualTo(orig.GeographicLocation));
+ Assert.That(copy.Transparency, Is.EqualTo(orig.Transparency));
+
+ Assert.That(Regex.Matches(serializedOrig, uidPattern, RegexOptions.Compiled, TimeSpan.FromSeconds(100)), Has.Count.EqualTo(1));
+ Assert.That(Regex.Matches(serializedCopy, uidPattern, RegexOptions.Compiled, TimeSpan.FromSeconds(100)), Has.Count.EqualTo(1));
+ });
+ }
+
+ [Test]
+ public void CopyFreeBusyTest()
+ {
+ var orig = new FreeBusy
+ {
+ Start = new CalDateTime(_now),
+ End = new CalDateTime(_later),
+ Entries = { new FreeBusyEntry { Language = "English", StartTime = new CalDateTime(2024, 10, 1), Duration = TimeSpan.FromDays(1), Status = FreeBusyStatus.Busy}}
+ };
+
+ var copy = orig.Copy();
+
+ Assert.Multiple(() =>
+ {
+ // Start/DtStart and End/DtEnd are the same
+ Assert.That(copy.Start, Is.EqualTo(orig.DtStart));
+ Assert.That(copy.End, Is.EqualTo(orig.DtEnd));
+ Assert.That(copy.Entries[0].Language, Is.EqualTo(orig.Entries[0].Language));
+ Assert.That(copy.Entries[0].StartTime, Is.EqualTo(orig.Entries[0].StartTime));
+ Assert.That(copy.Entries[0].Duration, Is.EqualTo(orig.Entries[0].Duration));
+ Assert.That(copy.Entries[0].Status, Is.EqualTo(orig.Entries[0].Status));
+ });
+ }
+
+ [Test]
+ public void CopyAlarmTest()
+ {
+ var orig = new Alarm
+ {
+ Action = AlarmAction.Display,
+ Trigger = new Trigger(TimeSpan.FromMinutes(15)),
+ Description = "Test Alarm"
+ };
+
+ var copy = orig.Copy();
+
+ Assert.Multiple(() =>
+ {
+ Assert.That(copy.Action, Is.EqualTo(orig.Action));
+ Assert.That(copy.Trigger, Is.EqualTo(orig.Trigger));
+ Assert.That(copy.Description, Is.EqualTo(orig.Description));
+ });
+ }
+
+ [Test]
+ public void CopyTodoTest()
+ {
+ var orig = new Todo
+ {
+ Summary = "Test Todo",
+ Description = "This is a test todo",
+ Due = new CalDateTime(DateTime.Now.AddDays(10)),
+ Priority = 1,
+ Contacts = new[] { "John", "Paul" },
+ Status = "NeedsAction"
+ };
+
+ var copy = orig.Copy();
+
+ Assert.Multiple(() =>
+ {
+ Assert.That(copy.Summary, Is.EqualTo(orig.Summary));
+ Assert.That(copy.Description, Is.EqualTo(orig.Description));
+ Assert.That(copy.Due, Is.EqualTo(orig.Due));
+ Assert.That(copy.Priority, Is.EqualTo(orig.Priority));
+ Assert.That(copy.Contacts, Is.EquivalentTo(orig.Contacts));
+ Assert.That(copy.Status, Is.EqualTo(orig.Status));
+ });
+ }
+
+ [Test]
+ public void CopyJournalTest()
+ {
+ var orig = new Journal
+ {
+ Summary = "Test Journal",
+ Description = "This is a test journal",
+ DtStart = new CalDateTime(DateTime.Now),
+ Categories = new List { "Category1", "Category2" },
+ Priority = 1,
+ Status = "Draft"
+ };
+
+ var copy = orig.Copy();
+
+ Assert.Multiple(() =>
+ {
+ Assert.That(copy.Summary, Is.EqualTo(orig.Summary));
+ Assert.That(copy.Description, Is.EqualTo(orig.Description));
+ Assert.That(copy.DtStart, Is.EqualTo(orig.DtStart));
+ Assert.That(copy.Categories, Is.EquivalentTo(orig.Categories));
+ Assert.That(copy.Priority, Is.EqualTo(orig.Priority));
+ Assert.That(copy.Status, Is.EqualTo(orig.Status));
+ });
+ }
+ }
+}
diff --git a/Ical.Net.Tests/CopyTest.cs b/Ical.Net.Tests/CopyTest.cs
deleted file mode 100644
index 0c9b2cdf..00000000
--- a/Ical.Net.Tests/CopyTest.cs
+++ /dev/null
@@ -1,77 +0,0 @@
-using Ical.Net.CalendarComponents;
-using Ical.Net.DataTypes;
-using Ical.Net.Serialization;
-using NUnit.Framework;
-using System;
-using System.Collections;
-using System.Text.RegularExpressions;
-
-namespace Ical.Net.Tests
-{
- [TestFixture]
- public class CopyTest
- {
- [Test, TestCaseSource(nameof(CopyCalendarTest_TestCases)), Category("Copy tests")]
- public void CopyCalendarTest(string calendarString)
- {
- var iCal1 = Calendar.Load(calendarString);
- var iCal2 = iCal1.Copy();
- SerializationTests.CompareCalendars(iCal1, iCal2);
- }
-
- public static IEnumerable CopyCalendarTest_TestCases()
- {
- yield return new TestCaseData(IcsFiles.Attachment3).SetName("Attachment3");
- yield return new TestCaseData(IcsFiles.Bug2148092).SetName("Bug2148092");
- yield return new TestCaseData(IcsFiles.CaseInsensitive1).SetName("CaseInsensitive1");
- yield return new TestCaseData(IcsFiles.CaseInsensitive2).SetName("CaseInsensitive2");
- yield return new TestCaseData(IcsFiles.CaseInsensitive3).SetName("CaseInsensitive3");
- yield return new TestCaseData(IcsFiles.Categories1).SetName("Categories1");
- yield return new TestCaseData(IcsFiles.Duration1).SetName("Duration1");
- yield return new TestCaseData(IcsFiles.Encoding1).SetName("Encoding1");
- yield return new TestCaseData(IcsFiles.Event1).SetName("Event1");
- yield return new TestCaseData(IcsFiles.Event2).SetName("Event2");
- yield return new TestCaseData(IcsFiles.Event3).SetName("Event3");
- yield return new TestCaseData(IcsFiles.Event4).SetName("Event4");
- yield return new TestCaseData(IcsFiles.GeographicLocation1).SetName("GeographicLocation1");
- yield return new TestCaseData(IcsFiles.Language1).SetName("Language1");
- yield return new TestCaseData(IcsFiles.Language2).SetName("Language2");
- yield return new TestCaseData(IcsFiles.Language3).SetName("Language3");
- yield return new TestCaseData(IcsFiles.TimeZone1).SetName("TimeZone1");
- yield return new TestCaseData(IcsFiles.TimeZone2).SetName("TimeZone2");
- yield return new TestCaseData(IcsFiles.TimeZone3).SetName("TimeZone3");
- yield return new TestCaseData(IcsFiles.XProperty1).SetName("XProperty1");
- yield return new TestCaseData(IcsFiles.XProperty2).SetName("XProperty2");
- }
-
- private static readonly DateTime _now = DateTime.Now;
- private static readonly DateTime _later = _now.AddHours(1);
-
- private static CalendarEvent GetSimpleEvent() => new CalendarEvent
- {
- DtStart = new CalDateTime(_now),
- DtEnd = new CalDateTime(_later),
- Duration = TimeSpan.FromHours(1),
- };
-
- private static string SerializeEvent(CalendarEvent e) => new CalendarSerializer().SerializeToString(new Calendar { Events = { e } });
-
- [Test]
- public void EventUid_Tests()
- {
- var e = GetSimpleEvent();
- e.Uid = "Hello";
- var copy = e.Copy();
- Assert.That(copy.Uid, Is.EqualTo(e.Uid));
-
- copy.Uid = "Goodbye";
-
- const string uidPattern = "UID:";
- var serializedOrig = SerializeEvent(e);
- Assert.That(Regex.Matches(serializedOrig, uidPattern), Has.Count.EqualTo(1));
-
- var serializedCopy = SerializeEvent(copy);
- Assert.That(Regex.Matches(serializedCopy, uidPattern), Has.Count.EqualTo(1));
- }
- }
-}
diff --git a/Ical.Net.Tests/DeserializationTests.cs b/Ical.Net.Tests/DeserializationTests.cs
index a4e5350e..e32d6fb0 100644
--- a/Ical.Net.Tests/DeserializationTests.cs
+++ b/Ical.Net.Tests/DeserializationTests.cs
@@ -229,8 +229,8 @@ public void Encoding2()
var evt = iCal.Events.First();
Assert.That(
- evt.Attachments[0].ToString(),
- Is.EqualTo("This is a test to try out base64 encoding without being too large.\r\n" +
+ evt.Attachments[0].ToString(),
+ Is.EqualTo("This is a test to try out base64 encoding without being too large.\r\n" +
"This is a test to try out base64 encoding without being too large.\r\n" +
"This is a test to try out base64 encoding without being too large.\r\n" +
"This is a test to try out base64 encoding without being too large.\r\n" +
@@ -242,7 +242,7 @@ public void Encoding2()
"This is a test to try out base64 encoding without being too large.\r\n" +
"This is a test to try out base64 encoding without being too large.\r\n" +
"This is a test to try out base64 encoding without being too large."),
- "Attached value does not match.");
+ "Attached value does not match.");
}
[Test]
diff --git a/Ical.Net.Tests/Ical.Net.Tests.csproj b/Ical.Net.Tests/Ical.Net.Tests.csproj
index b6d93fdd..dbb76431 100644
--- a/Ical.Net.Tests/Ical.Net.Tests.csproj
+++ b/Ical.Net.Tests/Ical.Net.Tests.csproj
@@ -3,6 +3,7 @@
net8.0;net6.0;net48
true
..\IcalNetStrongnameKey.snk
+ latest
diff --git a/Ical.Net.Tests/RecurrenceTests.cs b/Ical.Net.Tests/RecurrenceTests.cs
index 22a49157..ec52cef1 100644
--- a/Ical.Net.Tests/RecurrenceTests.cs
+++ b/Ical.Net.Tests/RecurrenceTests.cs
@@ -37,9 +37,10 @@ int eventIndex
.OrderBy(o => o.Period.StartTime)
.ToList();
- Assert.That(occurrences,
- Has.Count.EqualTo(dateTimes.Length),
- "There should be exactly " + dateTimes.Length + " occurrences; there were " + occurrences.Count);
+ Assert.That(
+ occurrences,
+Has.Count.EqualTo(dateTimes.Length),
+ "There should be exactly " + dateTimes.Length + " occurrences; there were " + occurrences.Count);
if (evt.RecurrenceRules.Count > 0)
{
diff --git a/Ical.Net.Tests/SerializationTests.cs b/Ical.Net.Tests/SerializationTests.cs
index 1516830c..a633c642 100644
--- a/Ical.Net.Tests/SerializationTests.cs
+++ b/Ical.Net.Tests/SerializationTests.cs
@@ -117,7 +117,7 @@ public static string InspectSerializedSection(string serialized, string sectionN
var end = serialized.IndexOf(searchFor, begin);
Assert.That(end, Is.Not.EqualTo(-1), () => string.Format(notFound, searchFor));
- var searchRegion = serialized.Substring(begin, end - begin + 1);
+ var searchRegion = serialized.Substring(begin, end - begin + searchFor.Length);
foreach (var e in elements)
{
@@ -284,14 +284,14 @@ public void EventPropertiesSerialized()
{
new Attendee("MAILTO:james@example.com")
{
- CommonName = "James James",
+ CommonName = "James",
Role = ParticipationRole.RequiredParticipant,
Rsvp = true,
ParticipationStatus = EventParticipationStatus.Tentative
},
new Attendee("MAILTO:mary@example.com")
{
- CommonName = "Mary Mary",
+ CommonName = "Mary",
Role = ParticipationRole.RequiredParticipant,
Rsvp = true,
ParticipationStatus = EventParticipationStatus.Accepted
@@ -301,7 +301,6 @@ public void EventPropertiesSerialized()
[Test, Category("Serialization")]
public void AttendeesSerialized()
{
- //ToDo: This test is broken as of 2016-07-13
var cal = new Calendar
{
Method = "REQUEST",
@@ -310,12 +309,14 @@ public void AttendeesSerialized()
var evt = AttendeeTest.VEventFactory();
cal.Events.Add(evt);
- const string org = "MAILTO:james@example.com";
+ // new Uri() creates lowercase for the "MAILTO:" part
+ // according to the RFC 2368 specification
+ const string org = "MAILTO:james@example.com";
evt.Organizer = new Organizer(org);
evt.Attendees.AddRange(_attendees);
- // However a bug, when a participation value is changed, ultimately re-serialises as an array (PARTSTAT=ACCEPTED,DECLINED)
+ // Changing the ParticipationStatus just keeps the last status
evt.Attendees[0].ParticipationStatus = EventParticipationStatus.Declined;
var serializer = new CalendarSerializer();
@@ -325,7 +326,7 @@ public void AttendeesSerialized()
foreach (var a in evt.Attendees)
{
- var vals = GetValues(vEvt, "ATTENDEE", a.Value.OriginalString);
+ var vals = GetValues(vEvt, "ATTENDEE", a.Value.ToString());
foreach (var v in new Dictionary
{
["CN"] = a.CommonName,
@@ -338,7 +339,7 @@ public void AttendeesSerialized()
Assert.Multiple(() =>
{
Assert.That(vals.ContainsKey(v.Key), Is.True, $"could not find key '{v.Key}'");
- Assert.That(vals[v.Key], Is.EqualTo(v.Value), $"ATENDEE prop '{v.Key}' differ");
+ Assert.That(vals[v.Key], Is.EqualTo(v.Value), $"ATTENDEE prop '{v.Key}' differ");
});
}
}
diff --git a/Ical.Net/CalendarComponents/Alarm.cs b/Ical.Net/CalendarComponents/Alarm.cs
index 6f0adb42..4d8fda1f 100644
--- a/Ical.Net/CalendarComponents/Alarm.cs
+++ b/Ical.Net/CalendarComponents/Alarm.cs
@@ -10,7 +10,6 @@ namespace Ical.Net.CalendarComponents
///
public class Alarm : CalendarComponent
{
- //ToDo: Implement IEquatable
public virtual string Action
{
get => Properties.Get(AlarmAction.Key);
@@ -177,4 +176,4 @@ protected virtual void AddRepeatedItems()
}
}
}
-}
\ No newline at end of file
+}
diff --git a/Ical.Net/CalendarComponents/CalendarComponent.cs b/Ical.Net/CalendarComponents/CalendarComponent.cs
index cf5b77e1..a34e1e25 100644
--- a/Ical.Net/CalendarComponents/CalendarComponent.cs
+++ b/Ical.Net/CalendarComponents/CalendarComponent.cs
@@ -37,6 +37,7 @@ protected override void OnDeserializing(StreamingContext context)
Initialize();
}
+ ///
public override void CopyFrom(ICopyable obj)
{
base.CopyFrom(obj);
@@ -50,7 +51,8 @@ public override void CopyFrom(ICopyable obj)
Properties.Clear();
foreach (var p in c.Properties)
{
- Properties.Add(p);
+ // Uses CalendarObjectBase.Copy() for a deep copy
+ Properties.Add(p.Copy());
}
}
diff --git a/Ical.Net/CalendarComponents/CalendarEvent.cs b/Ical.Net/CalendarComponents/CalendarEvent.cs
index 4f3243cf..272c9f9a 100644
--- a/Ical.Net/CalendarComponents/CalendarEvent.cs
+++ b/Ical.Net/CalendarComponents/CalendarEvent.cs
@@ -161,8 +161,10 @@ public string Location
///
/// Resources that will be used during the event.
- /// Conference room #2
- /// Projector
+ /// To change existing values, assign a new .
+ /// Examples:
+ /// Conference room, Projector
+ ///
///
public virtual IList Resources
{
diff --git a/Ical.Net/CalendarObject.cs b/Ical.Net/CalendarObject.cs
index 486edfcb..5cf150db 100644
--- a/Ical.Net/CalendarObject.cs
+++ b/Ical.Net/CalendarObject.cs
@@ -30,11 +30,8 @@ public CalendarObject(int line, int col) : this()
private void Initialize()
{
- //ToDo: I'm fairly certain this is ONLY used for null checking. If so, maybe it can just be a bool? CalendarObjectList is an empty object, and
- //ToDo: its constructor parameter is ignored
- _children = new CalendarObjectList(this);
+ _children = new CalendarObjectList();
_serviceProvider = new ServiceProvider();
-
_children.ItemAdded += Children_ItemAdded;
}
@@ -61,10 +58,10 @@ public override bool Equals(object obj)
public override int GetHashCode() => Name?.GetHashCode() ?? 0;
+ ///
public override void CopyFrom(ICopyable c)
{
- var obj = c as ICalendarObject;
- if (obj == null)
+ if (c is not ICalendarObject obj)
{
return;
}
@@ -74,12 +71,13 @@ public override void CopyFrom(ICopyable c)
Parent = obj.Parent;
Line = obj.Line;
Column = obj.Column;
-
+
// Add each child
Children.Clear();
foreach (var child in obj.Children)
{
- this.AddChild(child);
+ // Add a deep copy of the child instead of the child itself
+ this.AddChild(child.Copy());
}
}
@@ -99,21 +97,22 @@ public override void CopyFrom(ICopyable c)
public virtual string Name { get; set; }
///
- /// Returns the that this DDayiCalObject belongs to.
+ /// Gets the object.
+ /// The setter must be implemented in a derived class.
///
public virtual Calendar Calendar
{
get
{
ICalendarObject obj = this;
- while (!(obj is Calendar) && obj.Parent != null)
+ while (obj is not Net.Calendar && obj.Parent != null)
{
obj = obj.Parent;
}
return obj as Calendar;
}
- protected set { }
+ protected set => throw new NotSupportedException();
}
public virtual int Line { get; set; }
diff --git a/Ical.Net/CalendarObjectBase.cs b/Ical.Net/CalendarObjectBase.cs
index 03d28d96..b25d50c0 100644
--- a/Ical.Net/CalendarObjectBase.cs
+++ b/Ical.Net/CalendarObjectBase.cs
@@ -2,37 +2,33 @@
namespace Ical.Net
{
+ // This class should be declared as abstract
public class CalendarObjectBase : ICopyable, ILoadable
{
- private bool _mIsLoaded;
-
- public CalendarObjectBase()
- {
- _mIsLoaded = true;
- }
+ private bool _mIsLoaded = true;
///
- /// Copies values from the target object to the
- /// current object.
+ /// Makes a deep copy of the source
+ /// to the current object. This method must be overridden in a derived class.
///
- public virtual void CopyFrom(ICopyable c) { }
+ public virtual void CopyFrom(ICopyable obj)
+ {
+ throw new NotImplementedException("Must be implemented in a derived class.");
+ }
///
- /// Creates a copy of the object.
+ /// Creates a deep copy of the object.
///
- /// The copy of the object.
+ /// The copy of the object.
public virtual T Copy()
{
var type = GetType();
var obj = Activator.CreateInstance(type) as ICopyable;
+
+ if (obj is not T objOfT) return default(T);
- // Duplicate our values
- if (obj is T)
- {
- obj.CopyFrom(this);
- return (T)obj;
- }
- return default(T);
+ obj.CopyFrom(this);
+ return objOfT;
}
public virtual bool IsLoaded => _mIsLoaded;
diff --git a/Ical.Net/CalendarObjectList.cs b/Ical.Net/CalendarObjectList.cs
index 7dc19f3c..8edcb2c3 100644
--- a/Ical.Net/CalendarObjectList.cs
+++ b/Ical.Net/CalendarObjectList.cs
@@ -1,3 +1,4 @@
+using System.Diagnostics.CodeAnalysis;
using Ical.Net.Collections;
namespace Ical.Net
@@ -5,8 +6,8 @@ namespace Ical.Net
///
/// A collection of calendar objects.
///
+ [ExcludeFromCodeCoverage]
public class CalendarObjectList : GroupedList, ICalendarObjectList
{
- public CalendarObjectList(ICalendarObject parent) {}
}
}
\ No newline at end of file
diff --git a/Ical.Net/CalendarParameter.cs b/Ical.Net/CalendarParameter.cs
index f2c7a7a0..6b09314c 100644
--- a/Ical.Net/CalendarParameter.cs
+++ b/Ical.Net/CalendarParameter.cs
@@ -49,6 +49,7 @@ protected override void OnDeserializing(StreamingContext context)
Initialize();
}
+ ///
public override void CopyFrom(ICopyable c)
{
base.CopyFrom(c);
diff --git a/Ical.Net/CalendarProperty.cs b/Ical.Net/CalendarProperty.cs
index 8d60ea5d..294293fc 100644
--- a/Ical.Net/CalendarProperty.cs
+++ b/Ical.Net/CalendarProperty.cs
@@ -61,12 +61,12 @@ public virtual void AddParameter(CalendarParameter p)
Parameters.Add(p);
}
+ ///
public override void CopyFrom(ICopyable obj)
{
base.CopyFrom(obj);
- var p = obj as ICalendarProperty;
- if (p == null)
+ if (obj is not ICalendarProperty p)
{
return;
}
@@ -124,7 +124,9 @@ public virtual void SetValue(IEnumerable