I want to send a function 2 parameters.
1. Type of class
2.Name of object.
In the new function I want to create the object by the type and the name that was given.
for example:
private void CreateColumns()
{
try
{
CreateColumn(typeof(DataGridViewTextBoxColumn),"customerFolderID");
CreateColumn(typeof(DataGridViewImageColumn),"customerName");
....
private void CreateColumn(Type ColumnType, string ColumnName)
{
try
{
...
I thought I can use reflection:
object Instance = Activator.CreateInstance(ColumnType);
but then how can I do something like this:
Instance ColumnName = new Instance();
The motivation is to replace those lines:
DataGridViewTextBoxColumn customerFolderID = new DataGridViewTextBoxColumn();
dgv_CustomersGrid.Columns.Add(customerFolderID);
DataGridViewImageColumn customerName = new DataGridViewImageColumn();
dgv_CustomersGrid.Columns.Add(customerName);
is there a way ?
is there any alternative?
maybe I should use dynamic somehow (I don't familiar with this yet) ?
Related
What is the correct syntax for a string expression meant to reference a call to a static function, when passed as a parameter to ExpressionEvaluatingSqlParameterSourceFactory?
As an example, I have a static function that returns a java.util.Date within a utility class:
public class DateTimeUtils {
private DateTimeUtils() {throw new IllegalStateException("Utility class");}
public static Date currentDeliveryDate() {
ZonedDateTime today = ZonedDateTime.now(ZoneOffset.UTC);
return new DateTime(
today.getYear(),
today.getMonthValue(),
today.getDayOfMonth(),
5,
0,
0)
.toDate();
}
I want to use the result of that function as a SQL parameter. The SQL is along the lines of
select zip
from delivery_status
where delivery_date = :deliverydate
And setting the parameter goes a little something like this:
public SqlParameterSourceFactory sourceFactory() {
ExpressionEvaluatingSqlParameterSourceFactory sourceFactory =
new ExpressionEvaluatingSqlParameterSourceFactory();
Map<String, String> params = new HashMap<>();
params.put("deliverydate", "#T(com.acme.util.DateTimeUtils).currentDeliveryDate()");
sourceFactory.setParameterExpressions(params);
return sourceFactory;
}
I've tried variations with/without T, pound sign, parenthesis, and fully qualified name, but I keep getting
org.springframework.dao.InvalidDataAccessApiUsageException: No value supplied for the SQL parameter 'deliverydate': No value registered for key 'deliverydate'
at org.springframework.jdbc.core.namedparam.NamedParameterUtils.buildValueArray(NamedParameterUtils.java:355)
Can one of you help me with the correct incantation?
Cheers, y'all.
Must work like this:
"T(com.acme.util.DateTimeUtils).currentDeliveryDate()"
No pound sign before T operator.
I have 2 classes, Class1 should be mapped to Class2. I do mapping with AutoMapper. I'd like to test my configuration of the mapper and for this purposes I'm using AutoFixture. Source class Class1 has property of type IList<>, destination class Class2 has a similar property but of type IEnumerable<>. To simplify test preparation I'm using AutoFixture (with AutoMoqCustomization) to initialize both source and destination objects. But after initializing property of type IEnumerable<> with AutoFixture, AutoMapper can't map the property.
Error text:
Error mapping types.
Mapping types: Class1 -> Class2 ConsoleApplication1.Class1 ->
ConsoleApplication1.Class2
Type Map configuration: Class1 -> Class2 ConsoleApplication1.Class1 ->
ConsoleApplication1.Class2
Property: Items
Could anybody help me to configure either AutoMapper or AutoFixture to make the mapping work? As a workaround I can assign null to the destination property, but I do not want to do this in the each test.
Simplified example of code:
public class AutoMapperTests
{
public static void TestCollectionsProperty()
{
Mapper.Initialize(cfg =>
{
cfg.CreateMap<ItemClass1, ItemClass2>();
cfg.CreateMap<Class1, Class2>();
});
var src = new Class1();
src.Items = new List<ItemClass1>()
{
new ItemClass1() { Text = "111" },
new ItemClass1() { Text = "222" }
};
var fixture = new Fixture();
var dst = fixture.Create<Class2>();
Mapper.Map(src, dst); //Error at this line of code
}
}
public class Class1
{
public IList<ItemClass1> Items { get; set; }
}
public class Class2
{
public IEnumerable<ItemClass2> Items { get; set; }
}
public class ItemClass1
{
public string Text { get; set; }
}
public class ItemClass2
{
public string Text { get; set; }
}
It's not really an AutoFixture issue per se. You can reproduce it without AutoFixture by instead creating dst like this:
var dst = new Class2();
dst.Items = Enumerable.Range(0, 1).Select(_ => new ItemClass2());
This will produce a similar error message:
Unable to cast object of type 'WhereSelectEnumerableIterator2[System.Int32,Ploeh.StackOverflow.Q45437098.ItemClass2]' to type 'System.Collections.Generic.IList1[Ploeh.StackOverflow.Q45437098.ItemClass2]'
That ought to be fairly self-explanatory: WhereSelectEnumerableIterator<int, ItemClass2> doesn't implement IList<ItemClass2>. AutoMapper attempts to make that cast, and fails.
The simplest fix is probably to avoid populating dst:
var dst = new Class2();
If you must use AutoFixture for this, you can do it like this:
var dst = fixture.Build<Class2>().OmitAutoProperties().Create();
Unless the Class2 constructor does something complex, however, I don't see the point of using AutoFixture in that scenario.
If, on the other hand, you do need dst to be populated, you just need to ensure that dst.Items is convertible to IList<ItemClass2>. One way to do that would be like this:
var dst = fixture.Create<Class2>();
dst.Items = dst.Items.ToList();
You could create a Customization to make sure that this happens automatically, but if you need help with that, please ask a new question (if you don't find one that already answers that question).
Here is a working example for your problem. As #Mark Seemann already told, Mapper.CreateMap has been deprecated, so this example is using the new structure.
Mapper.Initialize(cfg =>
{
cfg.CreateMap<ItemClass1, ItemClass2>();
cfg.CreateMap<Class1, Class2>();
});
var src = new Class1();
src.Items = new List<ItemClass1>()
{
new ItemClass1() { Text = "111" },
new ItemClass1() { Text = "222" }
};
var dest = Mapper.Map<Class1, Class2>(src);
AM requires IList because you're mapping to an existing list and that works by calling IList.Add.
I have a class that has 2 properties and a constructor:
public class Card
{
public int CardName {get;set;}
public bool IsActive {get;set;}
public Card (int cardName, bool isActive)
{
CardName = cardName;
IsActive = isActive;
}
}
How do I force the developer to use the constructor instead of doing the following:
var card = new Card{ CardName = "blab", IsActive = true };
On a side note, what is the statement above called? Is that a lazy loading statement?
You already have.
By not having an empty constructor you've removed the ability to use the object initializer method of creating an object.
This:
var card = new Card{ CardName = "blab", IsActive = true };
is the same as this
var card = new Card() { CardName = "blab", IsActive = true };
And in this context new Card() is not valid.
That depends on why you want to prevent the syntax in question.
The object initializer syntax is shorthand for setting a bunch of properties immediately after construction. That is, this:
var c = new Card { CardName = "foo", IsActive = true };
Is semantically identical to this:
var c = new Card();
c.CardName = "foo";
c.IsActive = true;
In both cases, a constructor does run, but its immediately followed by a series of property initializers to apply to the new object.
In your case, since there is no parameterless constructor, you cannot use the object initializer syntax the way you posted. However, it is legal to pass constructor parameters along with the object initializer, so the following would be legal for your class:
var c = new Card("", false) { CardName = "foo", IsActive = true };
(One could argue that this syntax makes the meaning of values more clear than simply passing them to a constructor; one could also argue its just being excessively stubborn :) I could go either way)
You could prevent this second syntax from working by removing the public setters for those properties. If your goal is to prevent the user from changing the values passed into the constructor, making an immutable Card object, for example, that would be the way to go.
I should point out, though, that if one of my juniors asked me this question at work I'd really want to know why they found it necessary to prevent object initialization from being used. There are valid reasons, of course, but they are usually not the source of the question. Object initializers are a good thing -- there are cases where this syntax is very convenient (particularly with LINQ) and I use it all the time.
If you do some kind of setup in the constructor based on the initial values, but those properties are public-settable, you already have to deal with a case where the user changes those values after construction. If your goal is merely to ensure that some "setup" code happens when the object is first constructed, put that code into a default constructor and chain them together:
public class Card
{
public string CardName { get; set; }
public bool IsActive { get; set; }
public Card()
{
// setup code here.
}
public Card ( string name, bool active )
: this()
{
this.CardName = name;
this.IsActive = active;
}
}
Declare the getters of the property as 'Private'.
Something like Public int CardName {private get; set;}.
I ran into a problem today when trying to set a field using FieldInfo.SetValue() passing a DynamicObject as the second argument. In my case, the field is a Guid and the DynamicObject should be able to convert itself to a one (using TryConvert) but it fails with an ArgumentException.
Some code that shows the problem:
// Simple impl of a DynamicObject to prove point
public class MyDynamicObj : DynamicObject
{
public override bool TryConvert(ConvertBinder binder, out object result)
{
result = null;
// Support converting this to a Guid
if (binder.Type == typeof(Guid))
{
result = Guid.NewGuid();
return true;
}
return false;
}
}
public class Test
{
public Guid MyField;
}
class Program
{
static void Main(string[] args)
{
dynamic myObj = new MyDynamicObj();
// This conversion works just fine
Guid guid = myObj;
var test = new Test();
var testField = typeof(Test).GetField("MyField");
// This, however, fails with:
// System.ArgumentException
// Object of type 'ConsoleApplication1.MyDynamicObj' cannot be converted to type 'System.Guid'.
testField.SetValue(test, myObj);
}
}
I'm not very familiar with the whole dynamicness of C# 4, but this felt to me like something that should work.. What am I doing wrong? Is there another way of doing this?
No, this shouldn't work - because the dynamic portion ends where your code ends. The compiler is calling a method with a signature of
void SetValue(Object obj, Object value)
That method call is dynamic, but it's just going to end up passing in a reference to the instance of MyDynamicObj. The call is resolved at execution time, but nothing in SetValue knows anything about the dynamic nature of the object whose reference you're passing in.
Basically you need to perform the dynamic part (the conversion in this case) in your code - the bit that involves the C# 4 compiler doing all its tricks. You've got to perform that conversion, and then you can call SetField.
To put it another way - it's a bit like calling SetField with a field of type XName, but passing in a string. Yes, there's a conversion from string to XName, but it's not SetField's job to work that out. That's the compiler's job.
Now, you can get this to work by making the compiler do some of the work, but you still need to do some with reflection:
static void Main(string[] args)
{
dynamic myObj = new MyDynamicObj();
var test = new Test();
var testField = typeof(Test).GetField("MyField");
var method = typeof(Program)
.GetMethod("Convert", BindingFlags.Static | BindingFlags.NonPublic);
method = method.MakeGenericMethod(testField.FieldType);
object converted = method.Invoke(null, new object[] {myObj});
testField.SetValue(test, converted);
}
static T Convert<T>(dynamic input)
{
return input;
}
You need an explicit cast to invoke the TryConvert:
testField.SetValue(test, (Guid)myObj);
Not sure if this is what you need though. Maybe there's some way to reflectively say ((DynamicObject)myObj).TryConvert(/*reflected destination type here*/, result)
Other attempts that failed, some of them require things like a certain interface be implemented, so they basically don't make use of TryConvert but maybe an alternative way to accomplish what you want:
Type secondType = testField.FieldType;
TypeConverter tc = TypeDescriptor.GetConverter(typeof(MyDynamicObj));
object secondObject = tc.ConvertTo(myObj,typeof( Guid));
//var secondObject = Convert.ChangeType(myObj, secondType);//Activator.CreateInstance(secondType);
//secondObject = myObj;
testField.SetValue(test, secondObject);
I've got a method similar to this, which loops through one set of data and uses a value of the first object to find an object in a second set of data:
private void someMethod(IQueryable<RemoteUser> source, IQueryable<LocalUser> targetData) {
// Loop all records in source data
foreach(var u in source) {
// Get keyvalue from source data and use it to find the matching record in targetData
var keyValue = u.id;
var object = from data.Where(o => o.id == keyValue).FirstOrDefault();
...
}
}
I'd like to make it more re-usable by passing in Func or using some other type of lambda and then convert the method to something I can use in a generic manner, i.e.:
private void someMethod<SourceT, TargetT>(IQueryable<SourceT> source, IQueryable<TargetT> targetData) {
....
}
What I'm not exactly sure on is how I can build a Func/Predicate/etc and pass it into the method. Keeping in mind that the "id" property will not be the same across all SourceT & TargetT properties.
To further explain, I'd like something where I can do this:
someMethod(RemoteUsers, LocalUsers, something here to say 'find the user using the userId property');
someMethod(RemoteProducts, LocalProducts, something here to say 'find the user using the productId property');
Here's the most basic implementation of your someMethod routine:
private void someMethod<S, T, P>(
IQueryable<S> source,
IQueryable<T> target,
Func<S, P> sourceSelector,
Func<T, P> targetSelector)
{
foreach(var s in source)
{
var sp = sourceSelector(s);
var #object = target
.Where(t => targetSelector(t).Equals(sp)).FirstOrDefault();
//...
}
}
This implementation keeps the structure of your original code, but this comes at a cost. You are effectively doing source.Count() * target.Count() queries against your database. You need to drop the use of foreach when working with IQueryable<>.
In fact, whenever you start writing code with foreach, you need to ask yourself if you can use a LINQ query to build and filter your data and make the foreach loop only do the "simplest" tasks.
Here's how to make the method work better:
private void someMethod2<S, T, P>(
IQueryable<S> source,
IQueryable<T> target,
Expression<Func<S, P>> sourceSelector,
Expression<Func<T, P>> targetSelector)
{
var query = source
.GroupJoin(
target,
sourceSelector,
targetSelector,
(s, ts) => ts.FirstOrDefault());
foreach(var #object in query)
{
//...
}
}
Note the use of Expression<Func<,>> and not just Func<,>. Also note the GroupJoin method call.