I've read a number of articles including this one on the subject of Empty or 'marker' interfaces. I have concluded that I cannot use custom attributes in my case as I need to be able to include the instance of a class to another method and, as these classes have nothing in common, I have no option but to use a 'marker' interface.
As an example, I might have
public class Foo
{
public int Id {get;set;}
public string Name {get;set;}
}
public class Bar
{
public Guid Identifier {get;set;}
public DateTime DueDate {get;set;}
}
and I need to pass them to a method in another class and because there may be many different types that need to be passed to the method, I've defined it like this...
public void MyMethod(IMyInterface model)
{
// Do something clever here
}
And All I've had to do to make this work is to 'implement' IMyInterface on Foo and Bar.
So to the question. I now find I need to call my MyMethod() method with an anonymous type created from a LINQ statement, so I tried this ...
var data = <Some Complex LINQ>.Select(a=> new { AString = a.Value1, ADecimal = a.Value2});
MyClass.MyMethod(data);
Sadly, I get the following compile-time error:
Error 202 Cannot convert type 'AnonymousType#1' to
'IMyInterface' via a reference
conversion, boxing conversion, unboxing conversion, wrapping
conversion, or null type conversion
Now, I know I could create a local class and use that in the same way as I have my standard classes, but my requirements mean that I'm going to have a lot of these LINQ queries in my up-coming set of work so, if possible, I'd like to find a solution that allows me to use Anonymous Types.
Does anyone know of a solution or workaround for the error I'm getting?
Related
I once again am struggling with reflection. I just give you the piece of code that my debugger does not bite:
public bool HandleCommand(string command)
{
MethodInfo m = methods.FirstOrDefault(t => t.GetCustomAttribute<CommandAttribute>().Name == command);
ICommandSet set =(m.DeclaringType)Activator.CreateInstance(m.DeclaringType);
m?.Invoke(set, null);
return true;
}
Basically, this code is inside a class called CommandHandler. When it's constructed, it loops over all the types in the executing assembly that implement a certain interface, and store all their methods that have a CustomAttribute attached to it in List; For this question's purpose I just assume that everything is working there. The attribute has just one property:
[AttributeUsage(AttributeTargets.Method)]
public class CommandAttribute : Attribute
{
public string Name { get; set; }
public CommandAttribute(string name)
{
Name = name;
}
}
Now in the method you saw above, the HandleCommand() method, I store the method which's name property is equal to the string I passed in in a MethodInfo m. Now my question essentially is, how I properly Invoke this method. m.Invoke needs an object that calls it, and because passing in "this" does not work, and examples online always passed in an instance of the class it was defined in, I figured I needed to create an instance of the class m was defined in and just pass this into the Invoke() method. In practice, this is a lot harder than I thought, and my best guess is what you can see above, with the activator.
ICommandSet set =(m.DeclaringType)Activator.CreateInstance(m.DeclaringType);
First of all, I know for sure that the class that m is declared in implements ICommandSet, because this is a creterium for a type to be inspected for the methods. So this is why I say "ICommandSet set". Then the Activator shall create this instance. But it does not work. The only error message provided states that m is a variable but is used like a type. However, when I pass it in as a param to Activator.CreateInstance() the compiler seems to dig it just fine. I absolutely don't know how I might fix this problem, as I don't really understand what is the problem. Is there anyone out there who can help me?
Also, all the methods are defined in different classes and even projects, so I don't know which class the methods are defined in.
The reason you're receiving this is your syntax is wrong. You cannot perform a cast with a variable dereference as the desire type. As you already know you wish to treat "set" as an "ICommandSet" cast to that instead.
var set = (ICommandSet) Activator.CreateInstance(m.DeclaringType);
You can also do it safe
var set = Activator.CreateInstance(m.DeclaringType) as ICommandSet;
my question could seem strange.
I use a class to encapsulate a method to not have to build a class of the interface (it's a bit long to explain and i don't want to go too far).
I would to know if it was possible to "extend" a generic class by add partial to "extend" its generic part. The purpose is to keep the same name class, but by add one (or more in the future) generic type to have the possibility to encapsulate any method, then pass the object containing the function and that include this interface.
I need to have:
new Foo<string>()
new Foo<string, int>()
...
I 'successful' made this i think, but perhaps it will generate some bug i can't imagine right now, or perhaps it's not.. how to say a good way to program.
Example:
Original
// A class to encapsulate a method "without parameter"
partial Foo<T>: Interface
{
public Func<Interface, T> FooLambda{ get; set; }
public virtual object Run()
{
return ToRun(this);
}
}
The method i need to pass (from another class)
void FooToEncapsulate(Interface patt)
{
//--- My code using an object with the interface pattern
}
Add another generic Type to Foo
The part to "extend" Foo
partial Foo<T,Y>: Foo<Y>
{
public new Func<Interface, T, Y> FooLambda{ get; set; }
public T Param {get;set;}
public override object Run()
{
return this.ToRun(this, Param);
}
}
The other method i need to pass (from another class)
void FooToEncaspulate(Interface patt, int param)
{
//--- My code using an object with the interface pattern
//--- and "param"
}
I have no problem for the while with this code, and i know it's something that could be strange, must i forget to use this technic, or could i think it was thought to work also like this ? Must i think if it compiles that means it's ok ? Is there another way to proceed like this without create a new class, and extend in same time on the generic part ?
(Sorry for my english)
Thx.
Edit:
I thought by using partial that could be a good idea, because i would to keep the same name for my class. After have read an answer and comment from Enigmativity, i tried without partial, and i have no errors relating to the name of the class when i compile.
If i well understand, the fact to add generic parameter to a class makes that create as many class than as "variants" depending on the generic type. "Partial" is useful to split code on several files on a basic class.
Is partial could be useful on code split with the same number of generic type ?
You don't need the word partial to extend a class with a single generic type to have two generic types. They are in fact two distinct classed.
This works fine:
class Foo<T>
{
}
class Foo<T, Y> : Foo<Y>
{
}
Now, as said in the comments, the rest of your code is quite flaky. If you can clean up the code I could provide you with a more answer that will be of more use to you.
Supposed I have some code like so:
// This represents some query that will return type T when executed.
public interface IQuery<T> { }
// An example query that returns bool
public class MyQuery : IQuery<bool> { }
// A separate class that's actually responsible for executing the queries.
public class Executor {
public T Execute<T>(IQuery<T> query)
}
// Usage
executor.Execute(new MyQuery()) // => true/false
No problems so far. But say I want to change my executor class such that it's responsible for instantiation of queries. Ideally I'd like usage to be something like:
// Usage
executor.Execute<MyQuery>() // => true/false
However, I can't seem to find a way to model this method signature. The closest I can get is:
public T Execute<TQuery, T>() where TQuery : IQuery<T>
The problem with this signature is that it requires all of the type parameters to be explicitly specified. There is no way for T to be inferred from TQuery since the generic type constraints are not considered when inferring type parameters.
So far the only workaround I've found is to set up a dummy argument to help with inference from the formal parameters. Basically going back to the original example but instead of passing an actual instance using new MyQuery() I can pass something like default(MyQuery). This is clunky though and the makes the API not at all obvious.
Is there some workaround that I'm missing?
I have an array of objects looking like this
public class ViewFilterData
{
public string Table { get; set; }
public string Field { get; set; }
public string Value { get; set; }
}
Due to calling function in separate dll, I need to pass this array as object[]. The above class is defined in both sections.
Project compiles, however when I try to cast each object in the array to above class, I get an invalidCastException, indicating that it "magically" know the originally class and refuse to cast it to the new one even though they are verbatim identical. Do I need to use reflection and create a new class marshalling over the array object by object and attribute by attribute? Or is there a simpler faster way? Thought about using scructs, however would rather not if possible.
"Unable to cast object of type 'Original.ViewFilterData' to type SeparateDLL.ViewFilterData'."
I call the function like this
var dt = oRepository.Page((object[])oDataRequest.Filters.ToArray())
and define it like this
public DataTable Page(object[] Filters)
Same name doesn't mean, they're of the same types. .NET cannot magically infer that.
for small objects, just write a quick LINQ query:
var separateDllFilters = oDataRequest.Filters.Select(of => new SeparateDLL.ViewFilterData
{
Table = of.Table,
// so on
}).ToArray();
however, if all the fields are same, (or even if they're not) you can use tools like AutoMapper to transform them easily.
typically, this is the order of solutions:
quick LINQ queries.
Extension methods to map the types.
Tools like AutoMapper
the solution you choose depends on factors like, how often you do this, how many callers need this, etc.
The above class is defined in both sections.
This is not valid in C#, each class is distinct from all other classes.
If you want to pass data between libraries you must use consistent types. The most popular method is to use a base library.
I need some help with a design issue I'm having. What I try to achieve is this:
I have a main class called Document. This Class has a list of Attribute classes. These Attribute classes have some common properties such as Identity and Name, but they differ in one property I call Value. The Value type is different for each different Attribute class and be of type string, integer, List, DateTime, float, List and also classes that consists of several properties. One example would be a class I would call PairAttribute that have 2 properties: Title and Description.
What I try to achieve is type safety for Value property of the Attribute child classes and that these child classes should be able to be added to the Attribute list in the Document class. I could have made only one Attribute class that have a Value property of type object and be done with it, but that is exactly what I try to avoid here.
The common properties (Identity and Name) should be placed in a base class I guess, lets call that AttributeBase class. But I want to have a child class, say StringAttribute, where the Value property is of type string, a IntegerAttribute class where the Value property is of type Integer, a StringListAttribute where the Value property is of type List, a PairAttribute class where the Value is a class with several properties, etc
Do you know how I can implement this? Is this a solution I should go for at all or is it a better ways of solving this type safety issue? I would appreciate code examples for clarification:)
You don't specify a language, but the feature described by the term "generics" (as used by Java and C#) is often called "parametric polymorphism" in other languages (like ML and Haskell). Conversely, the common meaning of "polymorphism" in Java and C# is actually more precisely called "subtype polymorphism".
The point is, whether you are using subtype polymorphism or parametric polymorphism, either way your problem calls for polymorphism, so I think you're on the right track.
The question really boils down to: when is parametric polymorphism better than subtype polymorphism? The answer is actually quite simple: when it requires you to write less code.
So, I'd suggest you prototype both approaches, and then see which one leads to simpler, easier to understand code. Then do it that way.
You may pass with a generic Attribute instead of inheritance/method polymorphism, but you will need to store them in some list and for that you will need an interface, because datastores in .Net cannot be a collections of undefined generic types, and if you would define them you would not be able to mix types inside:
public interface IAttribute {
string Identity { get; set; }
string Name { get; set; }
T GetValue<T>();
}
public class Attribute<T> : IAttribute
{
public string Identity { get; set; }
public string Name { get; set; }
public T Value { get; set; }
public Tret GetValue<Tret>() {
return (Tret)(Object)Value;
}
}
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
List<IAttribute> lst = new List<IAttribute>();
Attribute<string> attr1 = new Attribute<string>();
attr1.Value = "test";
Attribute<int> attr2 = new Attribute<int>();
attr2.Value = 2;
lst.Add(attr1);
lst.Add(attr2);
string attr1val = lst[0].GetValue<string>();
int attr2val = lst[1].GetValue<int>();
}
}
The (Tret)(Object) actually does not change type, it only boxes T and the (Tret) unboxes the value without using middle variables. This will of course fail if you miss the right type when calling GetValue<type>(). Even if compatible types are sent like Value is integer and you do GetValue<double>() -> because unboxing an integer into a double is not allowed.
Boxing/Unboxing is not as fast as casting but it ensures type safety is preserved, and there is at my knowledge no way to use generics with an compile time known interface in some other way.
So this should be type safe... and without a lot of code.