I guess... although reflection should generally be a last resort.
Would it be too hard to write a handful of methods to move a few
interrfaces?
You might want to think about the values that exist - i.e. if any are
collections, what should happen? or is it just standard settable
values?
I would probably be tempted to use generics to ensure that source and
target are suitable at compile time.
Example below (also covers readonly / writeonly).
Marc
using System.ComponentModel;
class Foo : IBar
{
public int Prop1 { get; set; }
public string Name { get; set; }
string IBar.Prop2 { get { return Name; } set { Name = value; } }
public bool Prop3 { get { return true; } }
public bool Prop4 { set { } }
}
interface IBar
{
int Prop1 { get; set; }
string Prop2 { get; set; }
bool Prop3 { get; }
bool Prop4 { set; }
}
class Program
{
static void Main()
{
Foo s = new Foo(), t = new Foo();
s.Name = "Fred";
s.Prop1 = 123;
BindData(s, t);
}
static void BindData<T>(T source, T target)
{
foreach (PropertyDescriptor prop in
TypeDescriptor.GetProperties(typeof(T)))
{
if (!prop.IsReadOnly) prop.SetValue(target,
prop.GetValue(source));
}
}
}
Marc Gravell - 18 Mar 2008 22:15 GMT
Oops - example should have used explicit generic call:
BindData<IBar>(s, t);
Otherwise the compiler infers T = Bar, and other properties (not part
of the interface) get copied. But just call it with the interface and
it will work - but it checks (at compile time) that both "source" and
"target" are suitable for T.
Marc
parez - 18 Mar 2008 23:05 GMT
> Oops - example should have used explicit generic call:
>
[quoted text clipped - 6 lines]
>
> Marc
Generic is definitely better than my way. i was going to add runtype
check but i guess i dont needed it now..
Thanks..yea it displayed all the properties. and the new thing display
only the interface properties.
parez - 18 Mar 2008 23:28 GMT
> Oops - example should have used explicit generic call:
>
[quoted text clipped - 6 lines]
>
> Marc
Is there any way i can force the user to pass IBar / or any other
interface for everycall?
Marc Gravell - 18 Mar 2008 23:46 GMT
Do you mean a *specific* interface, or just "an interface" ?
For the first, just use specific overloads on the public API:
BindData(IFoo source, IFoo target) {...}
BindData(IBar source, IBar target) {...}
Either doing things manually, or calling private BindData<T>
internally.
If you mean "an interface" - there is no generic constraint for this.
You could perhaps just add (to BindData<T>):
if (!typeof(T).IsInterface) throw new
InvalidOperationException(typeof(T).Name + " is not an interface");
Marc