Cannot implicitly convert type error - c#

I have subjected error. Why this error is comming, even I used same thing for my other classes.
ActCtrl ctrl = new ActCtrl();
Act action = ctrl.GetAct(companyID, actionID);
And in Act class.
public Act GetAct(string companyID, string actionID)
{
return (new ActBO()).GetAct(companyID, actionID);
}
And in BO class
public Act GetAct(string companyID, string actionID)
{
return (new ActDAO()).GetAct(companyID, actionID);
}
It gives me Cannot implicitly convert type 'Ent.Act' to 'ERP.Actions.Act' error on
Act action = ctrl.GetAct(companyID, actionID);
Any idea please. Thanks.

You've got two different Act classes - one in the Ent namespace, and one in ERP.Actions.Act.
Your action variable is of type ERP.Actions.Act, but ctrl.GetAct is returning an Ent.Act reference.
It's not clear what these classes are meant to be, but you may well want to try to collapse them to one class - or at least rename one of them for clarity.

Related

Generic interface argument from string

I am trying to add generics to my DAL. There's a list of EF entities and their corresponding repositories. These repositories implement a generic interface. I can't figure out how to instantiantiate the repository.
public T Create(T dtoEntity)
{
string entityClassName = dtoEntity.GetType().Name;
string repositoryClassName = entityClassName + "Repository";
try
{
string entityFullName = entitiesNamespace + entityClassName;
IEntityBase entity = (IEntityBase)assembly.CreateInstance(entityFullName)!;
string repositoryFullName = repositoryNamespace + repositoryClassName;
Type myType = Type.GetType("SmartVisionERP.Dal.SqlServer.Master.DataModel.Config_Accounts,SmartVisionERP.Dal.SqlServer.Master")!;
// IEntityBaseRepository<myType> repository = (IEntityBaseRepository<myType>)assembly.CreateInstance(repositoryFullName)!
IEntityBaseRepository<Config_Accounts> repository = (IEntityBaseRepository<Config_Accounts>)assembly.CreateInstance(repositoryFullName)!;
var list = repository.GetList();
}
catch (Exception)
{
throw;
}
return dtoEntity;
}
I am receiving a dtoEntity, I'm extracting the class name and then build the repository name out of it. For the scenario I am testing, these are "Config_Accounts" and "Config_AccountsRepository".
I am using reflection to instatiate the EF entity, has the same name, it's located in a different assembly. This line works properly, I have the entity.
The repository interface expects a T. IEntityBaseRepository<T> where T : class, IEntityBase, new()
I am getting the correct type in myType variable.
The commented line fails with the message "myType is a variable but is used as a type".
As soon as I write Config_Accounts instead of myType, it works, but this defeats the goal, I am trying to pass the actual type there.
I am out of ideas. Could anyone shed some light? How can I pass to that line a type generated from a string, in such way it actually works?
Thank you
========= EDIT =========
Based on help I received I have changed the code to look like below. I got an error stating "cannot instantiate an interface", which makes sense, so I passed the base class instead. I got the repository in an object, but the object does not expose any of the methods defined in the base class. I am assuming those will need to be exposed and used through more reflection, as suggested in one of the answers.
public T Create(T dtoEntity)
{
string entityClassName = dtoEntity.GetType().Name;
string repositoryClassName = entityClassName + "Repository";
try
{
string entityFullName = $"{entitiesNamespace}{entityClassName}";
IEntityBase entity = (IEntityBase)assembly.CreateInstance(entityFullName)!;
Type template = typeof(EntityBaseRepository<>);
Type myType = Type.GetType("SmartVisionERP.Dal.SqlServer.Master.DataModel.Config_Accounts,SmartVisionERP.Dal.SqlServer.Master")!;
Type genericType = template.MakeGenericType(myType);
object instance = Activator.CreateInstance(genericType);
//string repositoryFullName = repositoryNamespace + repositoryClassName;
//IEntityBaseRepository<Config_Accounts> repository = (IEntityBaseRepository<Config_Accounts>)assembly.CreateInstance(repositoryFullName)!;
//var list = repository.GetList();
}
catch (Exception)
{
throw;
}
return dtoEntity;
}
Generic type arguments need to be known at compile time ( i.e. when jitted). To construct object of a generic type at runtime you need use reflection. I.e. something as this answer ( Thanks to Marco for the link)
Type template = typeof(IEntityBaseRepository<>);
Type genericType = template.MakeGenericType(myType);
object instance = Activator.CreateInstance(genericType);
Ofc, to use the created object you need to use more reflection, since you do not have any compile-time type. You might end up with your compile time type, T, eventually so you can return it, but keep in mind that you will use a fair amount of reflection, and reflection tend to only produce runtime errors, and these errors might not be trivial to decipher.
As an alternative, if the goal is to map some set of types to some other types, one to one, you might consider using some other pattern, for example the visitor-pattern. This will require more code since you need some mapping code for each entity type. But it has the advantage of being type safe. Some types of implementations can force the developer to add any corresponding mappings when a new type is added, and therefore reduce the risk of runtime errors.
Since I do not know your particular circumstance I cannot know what the best solution is. But whenever dealing with reflection it can be a good idea to take a moment to consider if the benefit is worth the loss of type safety.

RuntimeBinderException when accessing ValueTuple item via dynamic

I am facing a really weird behavior of ValueTuple<T1,T2> passed from another assembly, accessed using dynamic. This code under specific circumstances throws RuntimeBinderException at the last line:
TupleTest(out var t);
(dynamic i1, dynamic i2) = t;
dynamic a = i1.Item1;
The message is:
'System.ValueType' does not contain a definition for 'Item1'
TupleTest function is defined in another assembly like this:
static void TupleTest(out ValueTuple<dynamic, dynamic> result) {
result = default;
result.Item1 = (new Priv(), new Priv());
result.Item2 = (new Priv(), new Priv());
}
Where empty class Priv { } has no visibility modifiers.
However, if I add public class Priv, the issue goes away.
I understand, that binder could have had problems accessing instance members of Priv, but in this case I am not getting to that yet! All I am trying to do is to access field Item1 of ValueTuple.
Interestingly, if Priv implements some public interface IFoo, then replacing result.Item1 = (new Priv(), new Priv()); with result.Item1 = ((IFoo)new Priv(), (IFoo)new Priv()) allows dynamic a = i1.Item1 to succeed.
Does that mean, that I can't use dynamic at all to access any public fields, whose value type is private (can only be possible with generics), defined elsewhere?
This happens because Priv is not accessible to the code trying to access it.
The accessibility of the types in dynamic must abide to the compiler rules.
The error message is not very helpful, though.

c# Linq to Sql dynamic Data Context assignment

`Hi,
Can somebody please give me a pointer on this? I have 8 servers each with 8 databases which look identical exept server/database name. We are talking thousands of tables.
I create my data contexts with sqlmetal.exe
After creating my data contexts, I import them into the application and then I run comparison scripts over the databases to compare results.
My problem is dynamically switching between data contexts.
Datacontext.DAL.DUK1 duk1sdi = new Datacontext.DAL.DUK1(connectionString);
Datacontext.DAL.DUK3 duk3sdi = new Datacontext.DAL.DUK3(connectionString);
string fromOne = runQuery(duk1sdi);
string fromThree = runQuery(duk3sdi);
public static string runQuery(DataContext duk)
{
var query =
from result in duk.TableA
select result.Total;
string returnString = query;
return returnString;
}
I have no problem with the query running when the duk is predefined, however how do I define and pass the datacontext to the function?
The error I get is:
Error 1 'System.Data.Linq.DataContext' does not contain a definition
for 'TableA' and no extension method 'TableA' accepting a first
argument of type 'System.Data.Linq.DataContext' could be found (are
you missing a using directive or an assembly reference?)
You could use the GetTable<T> method, where T is the type of the table, e.g. TableA.
public static string runQuery(DataContext duk) {
var table = duk.GetTable<TableA>();
var query = from result in table select result.Total;
...
}
However, all types of TableA will need to be the same type, strictly (I'm pretty sure).
Otherwise you would need to literally branch the logic for the handling of each context. Since you can extend your DataContext instances (in general, maybe not in your specific case) then you could have them share an interface that exposes a collection property of TableA, but you would need a higher level context wrapper to pass around then - unless you pass around the collection by altering the method signature.
You can use interfaces. Check this answer, but be sure to script the interfaces using a .tt file with the amount of tables you have.
Edit:
If you have generated contexts which you want to use interchangeably in a reusable method, you have the problem that the generated TableA classes are not reusable, since they are different types (even though the names may match, but that doesn't make them equal). Therefore you need to abstract the actual types, and one way to do this, is to use interfaces. You build your reusable method around an interface which abstracts the specific context-type and table-type. The downside is that you have to implement the interfaces on the generated contexts and tabletypes. This though is something you can solve using a .tt script.
Pseudo code:
// Define interface for table
public interface ITableA {
// ... properties
}
// Define interface for context
public interface IMyContext {
IQueryable<ITableA> TableA { get; }
}
// Extend TableA from DUK1
public partial class TableA: ITableA {
}
// Extend DUK1
public partial class Datacontext.DAL.DUK1: IMyContext {
IQueryable<ITableA> IMyContext.TableA {
get { return TableA; }
}
}
// Same for DUK3 and TableA FROM DUK3
// Finally, your code
Datacontext.DAL.DUK1 duk1sdi = new Datacontext.DAL.DUK1(connectionString);
Datacontext.DAL.DUK3 duk3sdi = new Datacontext.DAL.DUK3(connectionString);
string fromOne = runQuery(duk1sdi);
string fromThree = runQuery(duk3sdi);
public static string runQuery(IMyContext duk) {
// Note: method accepts interface, not specific context type
var query = from result in duk.TableA
select result.Total;
string returnString = query;
return returnString;
}
If your schema is identical between databases, why script the dbml for all of them? Just create one context with it's associated classes and dynamically switch out the connection string when instantiating the context.
var duk1sdi = new Datacontext.DAL.DUK1(connectionString1);
var duk3sdi = new Datacontext.DAL.DUK1(connectionString2);
Thanks, guys, I think I found the simplist solution for me based a bit of both your answers and by RTFM (Programming Microsoft Linq in Microsoft .NET Framework 4 by Paulo Pialorsi and Marco Russo)
In this way I don't have to use the large DBML files. It is a shame because I'm going to have to create hundreds of tables in this way, but I can now switch between connection strings on the fly.
First I create the table structure. (outside the program code block)
[Table(Name = "TableA")]
public class TableA
{
[Column] public int result;
}
Then I define the table for use:
Table<TableA> TableA = dc.GetTable<TableA>();
And then I can query from it:
var query =
from result in TableA
select TableA.result;

Calling static function via classname as a string in c#

My Problem
I have a Problem which i can not solve my self. I dont want to use so much code, because i have multiple Classes which extend another class (in my case its called "Data").
I have a log file, where each Data Group is beginning with a specific Group Name, for example "MitarbeiterSet". The abstract Data-Class is used to prefent to much code, where I implemented variables like "String[] data" (for the data beeing parsed from the log file e.g. < 101 4 3 6 3 30 80 2 0 0 1 300 >) or "static String parseInduction", which is used to determin, if this Class is the right one to create Objects from.
I have another Class, called ParseMonitor, which creates the StreamReader to parse the log-file. So if the right Class is found, i induct the setDataArray(StreamReader sr) function from the right Class, to parse the Data Array. (At this point i have to tell you, that i need those different Classes, because i need to upload them to a sql server specificly.)
This static function creates an object of it self and uses the parseLine(String line) Function to fill the object with data from the given line.
WHAT I NEED.
I want to call the static function of any class, just by having the name of this class. So i dont have to use that much code and be able to add more classes.
Later on i want to call every class and use the uploadToServer() to Upload it to the server.
Is this possible?
Since your static method is creating an instance of its class anyway, I suggest a different approach:
Create an interface that all classes that contain ParseLine can implement. (Change out the return type for the correct one):
public interface IParseLine
{
string ParseLine(string line);
}
Have all of the classes that contain ParseLine() implement IParseLine.
Create an instance of the class, cast it to an IParseLine, and execute the method:
IParseLine pl = Activator.CreateInstance(Type.GetType(className)) as IParseLine;
if (pl != null)
{
string parsedString = pl.ParseLine(line);
// ...
}
Edit From comments:
I want to create a while loop, which can be stated as followed:
while{!sr.EndofStream){ line = sr.ReadLine(); for(int i = 0; i <
classNames.length; i++){ if(line.Contains(classNames[i].MYINDICATOR){
CALL classNames[i] STATIC METHOD TO PARSE THE FOLLOWING LINES AND
CREATE DATA Objects of its Class } }
I didn't test this, but you can change the code to something like this (caching the reflection required to get MYINDICATOR):
IList<KeyValuePair<string, Type>> typeIndicators = classNames.Select(x => {
Type t = Type.GetType(x);
string indicator = (string)t.GetField("MYINDICATOR", BindingFlags.Public | BindingFlags.Static).GetValue(null);
return new KeyValuePair(indicator, t);
});
while (!sr.EndOfStream)
{
line = sr.ReadLine();
foreach (var types in typeIndicators)
{
if (line.Contains(types.Key))
{
IParseLine pl = Activator.CreateInstance(types.Value) as IParseLine;
if (pl != null)
{
string parsedString = pl.ParseLine(line);
}
}
}
}
I want to call the static function of any class, just by having the name of this class.
Well, you can use Type.GetType(className) to get a Type (note that the name needs to at least be fully qualified including the namespace, and may also need the assembly name depending on your exact scenario), then Type.GetMethod to get a MethodInfo. Finally, call MethodBase.Invoke to invoke the method.
If you could use typeof(Foo) instead of using a string, it would make the code simpler and more robust.
(Side-note: if your methods are really called parseLine, parseInduction, setDataArray etc, you should consider renaming them to follow .NET naming conventions :)
I think I see where you're coming from. In this simple exmaple below, I have a static class with a method in it (nothing amazing about that).
public static class MyStaticClass
{
public static DateTime GetTime()
{
return DateTime.Now;
}
}
If I want to invoke that method using reflection, I can just use the following code, but it does assume that the MyStaticClass class is available via a reference or inthe same project etc.
MethodInfo method = typeof(MyStaticClass).GetMethod("GetTime");
object result = method.Invoke(null, null);
if (result is DateTime)
{
Console.WriteLine(((DateTime)result).ToLongTimeString());
}
What you seem ot be asking for is a moethod of doing this when you don't have a reference to the class. In which case, try something like this:
MethodInfo method = Type.GetType("PocStaticReflect.MyStaticClass, PocStaticReflect, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null").GetMethod("GetTime");
object result = method.Invoke(null, null);
if (result is DateTime)
{
Console.WriteLine(((DateTime)result).ToLongTimeString());
}
Notice the fully qualified class name!
If you get that working, then you can simply loop though your class names and call the method you desire. Obviously, you'll probably want more error checking and more detail in the GetMethod() calls, but this shlud give you the gist of it. I've done something similar before looping though assemblies in a folder to pickup plug-ins for an application. That time, each of the classes implemented an interface to make them easier to locate, which may be helpful path to follow.
Or try this:
private static object GetResultFromStaticMethodClass(string qualifiedClassName, string method)
{
Type StaticClass = Type.GetType(qualifiedClassName);
MethodInfo methodInfo = StaticClass.GetMethod(method);
object result = methodInfo.Invoke(null, null);
return result;
}
Use:
object result = GetResultFromStaticMethodClass(
"Utilities.StringHelper,DaProject",
"ToList"
);
This call the static method ToList in the StringHelper class, in the Utilities namespace, in the DaProject project (same assembly and project name).
If you need parameters, add them in the second parameter in the methodInfo.Invoke(null, null) call

How to return Anonymous Type while using Linq [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
LINQ to SQL: Return anonymous type?
Do any one know how to return an anonymous type. I am using Linq where i need to return the following code
private <What's the return type to be provided here> SampleLinq(Int32 Num)
{
var query = (from dept in obj.DeptTable where dept.Id == Num select new { dept.DeptName, dept.DeptId });
return (query)
}
Sorry to say but you cannot return anonymous type out side the scope of method.
This is the alternate way to get anonmous type
// Method that returns anonymous type as object
object ReturnAnonymous()
{
return new { City="Prague", Name="Tomas" };
}
// Application entry-point
void Main()
{
// Get instance of anonymous type with 'City' and 'Name' properties
object o = ReturnAnonymous();
// This call to 'Cast' method converts first parameter (object) to the
// same type as the type of second parameter - which is in this case
// anonymous type with 'City' and 'Name' properties
var typed = Cast(o, new { City="", Name="" });
Console.WriteLine("Name={0}, City={1}", typed.Name, typed.City);
}
// Cast method - thanks to type inference when calling methods it
// is possible to cast object to type without knowing the type name
T Cast<T>(object obj, T type)
{
return (T)obj;
}
you can use it only for types in one assembly (two anonymous types from two different assemblies will be internally compiled to two different types that can't be converted using this trick).
Return Dynamic type:
public static dynamic getCustomer()
{
.....
var x = from c in customers
select new {Fname = c.FirstName};
return x;
}
static void Main(string[] args)
{
dynamic x = getCustomer();
Console.WriteLine(Enumerable.First(x).Fname);
Console.ReadKey();
}
you can't do that. that is why it is called anonymous. It doesn't have a name. But you always can cast it to object
Well, you can't actually do that, but here's a hack on this.
private object SampleLinq(Int32 Num)
{
return (from dept in obj.DeptTable where dept.Id == Num select new { dept.DeptName, dept.DeptId });
}
You can't return an Anonymous Type from a method.
You can create a simple Class to wrap the Anonymous Type, but you still need a Class (or cast to object).
Keep in mind, though, that if you cast to object there's no way to cast back. You'll need reflection to read any data.
The answers you see from the hack is a lot of work just to get an anonymous type through a method boundary. You shouldn't be doing this. If you need to pass something back from a method, you should be passing concrete types.
It depends what you looking to do with the return vale.
If your going to bind it in the UI
you can just rerun
IEnumerable or IQueryable.
If your going to use reflection on the return value just return type object
If your using c# 4.0 you can return a
dynamic type
If your using EF or Linq to SQL to further join a query comprised of your anonymous type you
can make a concrete class instead and
use the concrete placeholder
technique. For more details on this
technique I can give some assistance.
As others have mentioned though, you should really question whether returning an anonymous type form a method is the best way to solve the problem at hand. In general there is usually a better more pattern based approach that may require a bit more coding up front but may resulting in a more elegant design. This being said, I do believe there are legitimate cases such as with data binding where returning anonymous type instances can be perfectly acceptable.
UPDATE:
Just an interested tidbit I wanted to share in case those reading are not aware. Anonymous types are unique per their property names and types so lets say you have method A and method B in in both you create an anonymous type that has a single string typed property called Name by doing something like be code below.
public object A()
{
return new { Name = "Cid" }
}
public object B()
{
return new { Name = "Galuf" }
}
public void Test()
{
System.Diagnostics.Trace.Assert(A().GetType() == B().GetType());
}
Now even though this type is defined in two separate places the compiler only creates only creates a single shared type because they both have the same set of properties as defined by the property types and property names. In this respect the properties can be thought of as sort of a signature for the anonymous type. Using this knowledge there are different techniques that can be used for introspection into anonymous type instances that have been cast to object or deferred using the dynamic keyword. There are also nifty ways to work with anonymous types by using generic methods just as Linq does with methods in the static Enumerable and Queryable classes. This way you can do things like create a new instance of any given anonymous type and without using reflection. The trick is though that you have to use an instance of the anonymous type to pass to methods in order to have the type be inferred by the generic method. If anybody is interested in these topics further as they apply to the original posters question, leave a comment and I can try to clarify some of these techniques.

Categories

Resources